Aller au contenu

API Design-First avec Laravel : Une Implémentation Pratique

Appliquer la méthodologie design-first avec Laravel. Un complément au guide générique.

· 5 min read ·
Laravel API Design-First OpenAPI Bonnes Pratiques

TL;DR : Appliquez la methodologie API Design-First dans Laravel avec des packages dedies. Ecrivez votre spec OpenAPI, generez routes et requests avec laravel-openapi, validez avec Spectral, et lancez des tests de contrat en CI. La spec guide l’implementation — pas l’inverse.

J’ai longtemps codé mes APIs Laravel en mode “on verra bien”. Route, contrôleur, quelques tests, on ship. Ça marche — jusqu’au jour où le frontend attend un champ created_at et le backend renvoie date_creation. Trois heures de debug pour un problème de communication.

Le Design-First règle ça. On écrit le contrat avant le code. Tout le monde sait ce qui entre, ce qui sort, et dans quel format.


Le principe

Vous décrivez votre API dans une spec OpenAPI avant de toucher à Laravel. C’est le plan de la maison avant de couler la dalle.

Concrètement, ça donne trois choses :

  • Le frontend démarre sans attendre le backend (mock serveur sur la spec)
  • Les bugs d’intégration disparaissent quasi complètement
  • La doc est déjà faite quand le code est prêt

Écrire le contrat API

On commence par un fichier OpenAPI. Chaque endpoint y est décrit : méthode HTTP, paramètres, formats de requête et réponse, codes d’erreur.

openapi: 3.0.3
info:
  title: "API Utilisateurs"
  version: "1.0.0"
paths:
  /api/users/{id}:
    get:
      summary: Récupérer un utilisateur par ID
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Utilisateur trouvé
        "404":
          description: Utilisateur introuvable

Valider la spec en équipe

Ce fichier, je le fais relire par le frontend, la QA, le product. Pas besoin d’une réunion formelle — une PR avec la spec suffit. Chacun commente. Une fois mergé, c’est la source de vérité. On ne négocie plus les formats en plein sprint.


Scaffolder les routes et contrôleurs

La spec est validée. On passe à Laravel.

php artisan make:controller Api/UserController

Dans routes/api.php :

use App\Http\Controllers\Api\UserController;

Route::get('/users/{id}', [UserController::class, 'show']);

Premier réflexe : un stub qui renvoie des données en dur. Le frontend peut brancher ses appels immédiatement.

public function show(int $id)
{
    return response()->json([
        'id' => $id,
        'name' => 'Utilisateur Démo',
    ]);
}

Brancher la vraie logique

Une fois le stub en place et le frontend qui tourne, on remplace par le vrai code :

use App\Models\User;

public function show(int $id)
{
    $user = User::find($id);

    if (!$user) {
        return response()->json(['error' => 'Utilisateur introuvable'], 404);
    }

    return response()->json($user, 200);
}

Le contrat ne change pas. Seule l’implémentation évolue. C’est tout l’intérêt.


Valider les entrées

La validation Laravel, c’est du solide. Je m’en sers pour garantir que chaque requête respecte la spec :

use Illuminate\Support\Facades\Validator;

public function store(Request $request)
{
    $validator = Validator::make($request->all(), [
        'name' => 'required|string|max:255',
        'email' => 'required|email|unique:users',
    ]);

    if ($validator->fails()) {
        return response()->json(['errors' => $validator->errors()], 400);
    }

    $user = User::create($request->validated());

    return response()->json($user, 201);
}

Des erreurs claires en 400, des données propres en base. Les devs frontend savent exactement quoi afficher quand ça échoue.


Tester contre la spec

Les tests vérifient que l’implémentation colle au contrat. Pas de surprise en prod.

// tests/Feature/UserApiTest.php
public function test_retrieve_existing_user_successfully()
{
    $user = User::factory()->create();

    $response = $this->getJson("/api/users/{$user->id}");

    $response->assertStatus(200)
             ->assertJson([
                 'id' => $user->id,
                 'email' => $user->email,
             ]);
}

public function test_retrieve_nonexistent_user_returns_404()
{
    $response = $this->getJson("/api/users/9999");

    $response->assertStatus(404)
             ->assertJson([
                 'error' => 'Utilisateur introuvable',
             ]);
}

Je lance ces tests en CI. Si un dev change un format de réponse sans mettre à jour la spec, le pipeline casse. C’est voulu.


Générer la doc

Dernier maillon : la documentation auto-générée depuis la spec. L5-Swagger fait le travail :

composer require darkaonline/l5-swagger
php artisan l5-swagger:generate

La doc reste synchronisée avec le code. Plus de wiki obsolète que personne ne met à jour.


Ce que ça change au quotidien

Sur mes derniers projets Laravel, le Design-First a tué une catégorie entière de bugs — ceux liés aux malentendus entre frontend et backend. Le temps investi dans la spec se récupère dès la première intégration. Et quand un nouveau dev rejoint l’équipe, la spec OpenAPI lui donne le contexte en cinq minutes au lieu d’une demi-journée de fouille dans le code.

Questions frequentes

Peut-on utiliser API Design-First sur un projet Laravel existant ?

Oui. Commencez par documenter vos endpoints actuels dans une spec OpenAPI, puis adoptez progressivement le workflow spec-first pour les nouveaux endpoints. Pas besoin de tout reecrire.

Quels packages Laravel supportent le developpement Design-First ?

Les packages cles incluent laravel-openapi pour la generation de routes/requests depuis les specs, laravel-data pour les DTOs types, et Spectral (npm) pour le linting de specs.

Comment valider les reponses API contre la spec OpenAPI dans Laravel ?

Utilisez un middleware qui verifie les formes de reponse contre votre spec pendant les tests. Des packages comme openapi-httpfoundation-testing peuvent valider que vos reponses correspondent aux schemas declares.

Faut-il versionner la spec OpenAPI dans Git ?

Absolument. Le fichier de spec doit vivre dans votre depot a cote du code. Utilisez des pull requests pour revoir les changements de spec avant l’implementation.