Créer une API REST avec Laravel
David TouzetMise à jour le 10 août 20264 min de lectureLaravel est idéal pour construire une API REST. Le framework fournit tout, les routes dédiées, les contrôleurs de ressources, le formatage JSON avec les API Resources, la validation des entrées et l’authentification par jetons avec Sanctum. Voici les grandes étapes, de la première route jusqu’à la sécurisation de vos accès.
Définir les routes d’API Laravel
Vos points d’entrée d’API vivent dans routes/api.php, bien séparé des pages web. Laravel y ajoute automatiquement le préfixe /api.
- Déclarez une route de ressource avec apiResource pour couvrir les actions courantes, la lecture, la création, la mise à jour et la suppression.
- Respectez les verbes HTTP, GET pour lire, POST pour créer, PUT ou PATCH pour modifier, DELETE pour supprimer.
- Pensez au versionnage, un préfixe comme /v1 protège vos clients quand l’API évolue.
Si Laravel est encore nouveau pour vous, ce rappel des bases pose le décor avant de coder.
⚠ Première chose, le fichier n’existe plus par défaut. Depuis Laravel 11, routes/api.php n’est pas créé à l’installation. Une commande le pose et branche tout ce qu’il faut.
php artisan install:api
Puis les routes, dans routes/api.php.
use App\Http\Controllers\Api\ClientController;
use Illuminate\Support\Facades\Route;
// Les 7 routes REST d’un coup. Toutes seront préfixées par /api automatiquement.
Route::apiResource('clients', ClientController::class);
// Et celles qui exigent un jeton valide.
Route::middleware('auth:sanctum')->group(function () {
Route::get('/moi', fn (Request $r) => $r->user());
Route::apiResource('factures', FactureController::class);
});
Le contrôle, avant même d’écrire le contrôleur.
php artisan route:list --path=api
Contrôleurs et API Resources Laravel
Un contrôleur de ressource regroupe la logique de chaque action dans une classe claire. Générez-le avec l’option resource, puis remplissez chaque méthode.
- Utilisez Eloquent pour lire et écrire vos données.
- Formatez chaque réponse avec une API Resource, elle transforme votre modèle en JSON propre et masque les champs sensibles.
- Ajoutez la pagination sur les listes, elle évite de renvoyer des milliers de lignes d’un seul coup et limite le problème des requêtes en cascade.
Pour prendre ces classes en main pas à pas, ce guide pour débuter avec Laravel aide à aller vite.
Le contrôleur, généré en 1 commande.
php artisan make:controller Api/ClientController --api --model=Client
php artisan make:resource ClientResource
La ressource, qui décide de ce qui sort. C’est elle qui vous évite d’exposer par accident un mot de passe ou une colonne interne.
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ClientResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->id,
'nom' => $this->nom,
'email' => $this->email,
'cree_le' => $this->created_at->toIso8601String(),
// whenLoaded évite la requête en trop si la relation n’a pas été chargée.
'factures' => FactureResource::collection($this->whenLoaded('factures')),
];
}
}
Et le contrôleur qui s’en sert.
public function index()
{
// Le with() charge la relation en 1 requête au lieu d’une par client.
return ClientResource::collection(Client::with('factures')->paginate(20));
}
public function show(Client $client)
{
return new ClientResource($client->load('factures'));
}
⚠ Ne renvoyez jamais le modèle directement. return Client::all(); expose toutes les colonnes de la table, y compris celles que vous ajouterez dans 6 mois sans y penser. La ressource est votre seule barrière.
Valider les données et gérer les erreurs d’API
Une API sérieuse ne fait jamais confiance aux données reçues. Laravel valide les entrées avec les Form Requests, des classes dédiées qui portent vos règles.
- Déclarez vos règles dans une Form Request, le contrôleur reste léger et lisible.
- Renvoyez des codes de statut justes, 200 pour un succès, 201 pour une création, 422 pour une donnée invalide, 404 pour une ressource absente.
- Soignez le format des erreurs, un message JSON clair aide qui consomme votre API à corriger vite.
La validation dans une classe dédiée, pas dans le contrôleur.
php artisan make:request StoreClientRequest
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreClientRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'nom' => ['required', 'string', 'max:120'],
'email' => ['required', 'email', 'unique:clients,email'],
'telephone' => ['nullable', 'string', 'max:20'],
];
}
public function messages(): array
{
return ['email.unique' => 'Ce client existe déjà.'];
}
}
Ce que Laravel fait tout seul avec ça. Sur une requête d’API, l’échec de validation renvoie automatiquement un 422 avec le détail par champ. Vous n’écrivez aucune gestion d’erreur.
{
"message": "Ce client existe déjà.",
"errors": { "email": ["Ce client existe déjà."] }
}
⚠ À condition que le client envoie le bon en-tête. Sans Accept: application/json, Laravel croit parler à un navigateur et renvoie une redirection au lieu du 422. C’est la cause numéro 1 des « mon API ne renvoie pas mes erreurs ».
curl -s -X POST https://api.exemple.fr/api/clients \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"nom":"Test"}'
Sécuriser l’accès avec Laravel Sanctum
La plupart des API demandent une authentification. Laravel Sanctum délivre des jetons que le client envoie dans l’en-tête Authorization à chaque requête.
- Installez Sanctum, puis protégez vos routes avec son middleware d’authentification.
- Choisissez Sanctum pour une SPA ou une API simple, Passport pour un besoin OAuth2 complet.
- Limitez le débit avec le throttling pour freiner les abus et protéger votre serveur.
Pour aller plus loin, notre article sur l’authentification et la sécurité dans Laravel détaille chaque option.
Une interface mal conçue se paie à chaque évolution, pendant des années. Nous en construisons régulièrement dans le cadre de projets sur mesure.
Créer un jeton pour un utilisateur.
// Les capacités listées limitent ce que le jeton peut faire, ne mettez pas ['*'] par défaut.
$jeton = $utilisateur->createToken('application-mobile', ['clients:lire'])->plainTextToken;
return response()->json(['token' => $jeton]);
⚠ La valeur en clair ne s’affiche qu’une fois. Laravel ne stocke qu’une empreinte. Si le client la perd, on n’en génère pas une copie, on en crée un nouveau et on révoque l’ancien.
L’appeler depuis n’importe où.
curl -s https://api.exemple.fr/api/moi \
-H "Accept: application/json" \
-H "Authorization: Bearer 1|VotreJetonIci"
Vérifier une capacité dans le code.
if (! $request->user()->tokenCan('clients:lire')) {
abort(403, 'Ce jeton n’a pas le droit de lire les clients.');
}
Et la révocation, à prévoir dès le premier jour.
$request->user()->currentAccessToken()->delete(); // déconnexion de l’appareil courant
$request->user()->tokens()->delete(); // révocation de tous les appareils
⚠ Le point que presque tout le monde oublie. Un jeton Sanctum n’expire pas par défaut. Réglez expiration dans config/sanctum.php, en minutes, sinon un jeton volé reste valable indéfiniment.
'expiration' => 60 * 24 * 30, // 30 jours
Les liens à garder sous la main
Gardez ces pages ouvertes pendant que vous construisez votre API.
Questions fréquentes
Une application Laravel sur mesure
Laravel permet des outils web puissants, on les met à votre service. On conçoit et développe votre application à Montpellier, robuste et évolutive.
Faire le point sur votre siteDes agents IA pour votre outil web
L’Agent Webmaster maintient votre application, l’Agent Cybersécurité la protège et l’Agent Veille technique anticipe les évolutions. 12 agents IA au travail.
Voir les 12 agents