aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webontwikkeling

Laravel API bouwen: RESTful endpoint-ontwerp

Een Laravel API bouwen geeft je, mits goed gedaan, een solide basis waar zowel een mobiele app als een single-page (SPA) front-end met vertrouwen op kunnen voortbouwen. In dit artikel beginnen we niet met een lege lijst endpoints; in plaats daarvan ontwerpen we een echte REST API rond een consistent resource-model, een schone JSON-uitvoer en een toekomstgerichte versioneringsstrategie. Het doel is geen API die louter "werkt", maar een die onderhoudbaar en voorspelbaar is en waar clients op kunnen vertrouwen.

Denken in resources, niet in acties

De kern van RESTful ontwerp is het plaatsen van resources in je URL's, niet van acties. In plaats van werkwoord-zware adressen zoals /api/createPost benoem je de resource als zelfstandig naamwoord en laat je de HTTP-methode de actie uitdrukken:

  • GET /api/posts — lijst opvragen
  • POST /api/posts — aanmaken
  • GET /api/posts/{id} — één record tonen
  • PUT/PATCH /api/posts/{id} — bijwerken
  • DELETE /api/posts/{id} — verwijderen

Laravel ondersteunt dit patroon rechtstreeks. De definitie Route::apiResource() genereert de vijf bovenstaande routes in één regel; anders dan de klassieke resource in web.php slaat het de create- en edit-routes over die formulieren tonen — want een API heeft geen HTML-formulieren.

Routes opzetten met een resource controller

Genereer eerst een controller met de --api-vlag:

php artisan make:controller Api/V1/PostController --api --model=Post

Koppel hem vervolgens in één regel in routes/api.php:

use App\Http\Controllers\Api\V1\PostController;

Route::apiResource('posts', PostController::class);

Dit koppelt de methodes index, store, show, update en destroy automatisch aan de juiste HTTP-werkwoorden. De routeparameter {post} verandert, mits getypehint, direct in het bijbehorende Post-object via Laravels route model binding; wordt er geen record gevonden, dan geeft Laravel uit zichzelf een 404 terug:

public function show(Post $post)
{
    return new PostResource($post);
}

JSON-uitvoer vormgeven met API Resources

Het model rechtstreeks teruggeven met return $post; werkt, maar is gevaarlijk: elke databasekolom (interne notities, password, tijdstempels) lekt ongewijzigd naar buiten, en de client breekt telkens als het schema verandert. Gebruik in plaats daarvan een API Resource-klasse — een transformatielaag waarin je de JSON-representatie van je model expliciet definieert.

php artisan make:resource PostResource

Vervolgens bepaal jij welke velden naar buiten gaan, en onder welke namen:

public function toArray($request): array
{
    return [
        'id'         => $this->id,
        'title'      => $this->title,
        'body'       => $this->body,
        'author'     => new UserResource($this->whenLoaded('user')),
        'created_at' => $this->created_at->toIso8601String(),
    ];
}

whenLoaded() voegt relationele data alleen toe wanneer die daadwerkelijk eager-loaded is — een praktische manier om het N+1-queryprobleem te vermijden. Om een collectie terug te geven gebruik je PostResource::collection($posts). Wil je ook metadata zoals het totale aantal pagina's teruggeven, dan kun je in index een paginator rechtstreeks aan de resource doorgeven; Laravel produceert de paginatielinks automatisch onder links en meta.

Validatie en foutmeldingen

Om binnenkomende data te valideren zonder de controller op te blazen, zijn Form Request-klassen ideaal:

php artisan make:request StorePostRequest
public function rules(): array
{
    return [
        'title' => ['required', 'string', 'max:255'],
        'body'  => ['required', 'string'],
    ];
}

Wanneer je hem in de controllermethode typehint, valideert Laravel het verzoek automatisch; bij een regelschending krijgt een client die de header Accept: application/json stuurt een 422 Unprocessable Content-statuscode samen met foutmeldingen per veld. Dit is de basis van een consistent foutcontract in REST API's: 200/201 succes, 401 authenticatie ontbreekt, 403 niet geautoriseerd, 404 niet gevonden, 422 validatiefout. Deze codes consistent gebruiken maakt foutafhandeling aan de clientkant voorspelbaar.

Versionering: je API toekomstbestendig maken

Zodra een API is gepubliceerd, wordt het lastig om hem te wijzigen zonder de clients die hem gebruiken te breken. Het antwoord is versionering. De meest gangbare en meest expliciete methode is de versie in het URL-pad zetten:

Route::prefix('v1')->group(function () {
    Route::apiResource('posts', \App\Http\Controllers\Api\V1\PostController::class);
});

Zo blijft /api/v1/posts stabiel; wanneer er uiteindelijk een incompatibele wijziging nodig is, open je een nieuwe versie met een V2-namespace en een v2-prefix, terwijl je de oude nog een tijd in de lucht houdt. Controllers opsplitsen in versiemappen zoals App\Http\Controllers\Api\V1 houdt ook de codebase fysiek netjes. Je kunt de versie alternatief in de Accept-header meegeven (media type versioning), maar de URL-gebaseerde aanpak is praktischer, zowel om in een browser te testen als om in logs te traceren.

Authenticatie en rate limiting

Om niet-publieke endpoints te beschermen is Laravels Sanctum-pakket de voorkeursoplossing, zowel voor cookie-gebaseerde SPA-sessies als voor toegang op basis van tokens. Je groepeert beveiligde routes met de auth:sanctum-middleware:

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('posts', PostController::class)
        ->except(['index', 'show']);
});

Hier blijven de lees-endpoints publiek terwijl de schrijf-endpoints authenticatie vereisen. Het is ook goede praktijk om met de throttle-middleware een rate limit toe te voegen om misbruik te voorkomen; Laravels RateLimiter laat je het aantal verzoeken per minuut per gebruiker of per IP definiëren.

Veelgestelde vragen

Wat is het verschil tussen apiResource en een gewone resource?

Route::resource() genereert zeven routes, waarvan er twee (create, edit) bedoeld zijn om HTML-formulieren te tonen. Route::apiResource() slaat die twee over en laat alleen de vijf data-teruggevende routes over — precies wat je nodig hebt in een JSON API zonder formulierweergave.

Waarom een API Resource gebruiken in plaats van het model direct teruggeven?

Omdat een API Resource je externe contract scheidt van je databaseschema. Zelfs als je een kolom hernoemt of een gevoelig veld toevoegt, verandert of lekt de uitgaande JSON niet, tenzij je dat zelf kiest. Dat is cruciaal voor zowel beveiliging als achterwaartse compatibiliteit.

Heb ik versionering vanaf het begin nodig?

Voor één kleine client is een v1-prefix niet verplicht, maar de kosten om hem toe te voegen zijn vrijwel nul. Het pad vanaf dag één als /api/v1 instellen geeft je enorme flexibiliteit wanneer er later een brekende wijziging nodig is; achteraf toevoegen vereist het migreren van alle clients.

Wil je een solide basis voor je API? Ik kan je helpen een schaalbare Laravel REST API te ontwerpen — van resource controllers tot versionering en authenticatie. Neem contact op en laten we je project samen plannen.

Devamı için