Chapitre 1 : Routage
Le fichier api.php définit toutes les routes de l'API.
Structure de base
<?php
// pwa/api.php
require_once '../smartmaker-api-prepend.php';
use SmartAuth\Api\AuthController;
use SmartAuth\Api\RouteController as Route;
use MonModule\Api\ItemController;
// Routes d'authentification (SmartAuth)
Route::get('login', AuthController::class, 'index');
Route::post('login', AuthController::class, 'login');
Route::get('refresh', AuthController::class, 'refresh');
Route::post('logout', AuthController::class, 'logout', true);
// Vos routes métier
Route::get('items', ItemController::class, 'index', true);
Route::get('items/{id}', ItemController::class, 'show', true);
Route::post('items', ItemController::class, 'create', true);
Route::put('items/{id}', ItemController::class, 'update', true);
Route::delete('items/{id}', ItemController::class, 'delete', true);
// Fallback (aucune route ne correspond)
json_reply('Access denied', 403);
Syntaxe des routes
Route::action(path, Controller::class, method, protected);
| Paramètre | Description |
|---|---|
| action | Méthode HTTP : get, post, put, delete |
| path | Chemin de l'API (ex: items, items/{id}) |
| Controller::class | Classe PHP à appeler |
| method | Méthode de la classe |
| protected | true = authentification requise |
Routes publiques vs protégées
// Route publique (accessible sans token)
Route::get('public/info', InfoController::class, 'index', false);
Route::get('public/info', InfoController::class, 'index'); // false par défaut
// Route protégée (token JWT requis)
Route::get('items', ItemController::class, 'index', true);
Paramètres dynamiques
Les paramètres entre accolades sont passés au controller :
// Route
Route::get('items/{id}', ItemController::class, 'show', true);
Route::get('items/{id}/files/{fileId}', ItemController::class, 'getFile', true);
// Appel : GET /items/123
// Dans le controller :
public function show($payload)
{
$id = $payload['id']; // 123
}
// Appel : GET /items/123/files/456
// Dans le controller :
public function getFile($payload)
{
$id = $payload['id']; // 123
$fileId = $payload['fileId']; // 456
}
Données POST/PUT
Les données JSON sont automatiquement parsées :
// Route
Route::post('items', ItemController::class, 'create', true);
// Appel : POST /items avec body { "label": "Test", "price": 29.99 }
// Dans le controller :
public function create($payload)
{
$label = $payload['label']; // "Test"
$price = $payload['price']; // 29.99
}
Exemple complet
<?php
// pwa/api.php
require_once '../smartmaker-api-prepend.php';
use SmartAuth\Api\AuthController;
use SmartAuth\Api\RouteController as Route;
use MonModule\Api\ProductController;
use MonModule\Api\CategoryController;
use MonModule\Api\FileController;
// ========================================
// AUTHENTIFICATION (SmartAuth)
// ========================================
Route::get('login', AuthController::class, 'index');
Route::post('login', AuthController::class, 'login');
Route::get('refresh', AuthController::class, 'refresh');
Route::post('logout', AuthController::class, 'logout', true);
Route::post('device', AuthController::class, 'device', true);
// ========================================
// PRODUITS
// ========================================
Route::get('products', ProductController::class, 'index', true);
Route::get('products/{id}', ProductController::class, 'show', true);
Route::post('products', ProductController::class, 'create', true);
Route::put('products/{id}', ProductController::class, 'update', true);
Route::delete('products/{id}', ProductController::class, 'delete', true);
// Recherche avec filtres
Route::post('products/search', ProductController::class, 'search', true);
// ========================================
// CATÉGORIES
// ========================================
Route::get('categories', CategoryController::class, 'index', true);
Route::get('categories/{id}', CategoryController::class, 'show', true);
// ========================================
// FICHIERS
// ========================================
Route::get('files/{element}/{parentId}/{ref}',
FileController::class, 'download', true);
Route::post('files/{element}/{parentId}',
FileController::class, 'upload', true);
// ========================================
// ROUTES PUBLIQUES
// ========================================
Route::get('public/info', InfoController::class, 'index');
// ========================================
// FALLBACK
// ========================================
json_reply('Access denied', 403);
Le fichier smartmaker-api-prepend.php
Ce fichier (généré par SmartBoot) initialise l'environnement :
<?php
// smartmaker-api-prepend.php
// Headers Dolibarr obligatoires
$res = 0;
if (!$res && file_exists("../main.inc.php")) {
$res = @include "../main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
// Charger SmartAuth
require_once DOL_DOCUMENT_ROOT . '/smartauth/class/api.class.php';
// Autoloader pour les classes du module
spl_autoload_register(function ($class) {
$prefix = 'MonModule\\Api\\';
$base_dir = __DIR__ . '/smartmaker-api/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
Réponses JSON
Les controllers retournent un tableau [données, code HTTP] :
// Succès
return [['items' => $items], 200];
return [['id' => $newId], 201]; // Created
return ['Updated', 200];
// Erreurs
return ['Not Found', 404];
return ['Bad Request', 400];
return ['Forbidden', 403];
return ['Server Error', 500];
Points clés à retenir
- Route::action() pour définir chaque endpoint
- true en dernier paramètre pour les routes authentifiées
- Paramètres dynamiques avec {nom}
- Fallback obligatoire en fin de fichier
- Le controller reçoit tout dans $payload