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

Laravel-API erstellen: RESTful-Endpoint-Design

Eine Laravel-API erstellen liefert dir, richtig gemacht, ein solides Fundament, auf dem sowohl eine mobile App als auch ein Single-Page-Frontend (SPA) mit Zuversicht aufbauen können. In diesem Artikel starten wir nicht mit einer leeren Endpoint-Liste; stattdessen entwerfen wir eine echte REST-API rund um ein konsistentes Ressourcenmodell, eine saubere JSON-Ausgabe und eine zukunftsorientierte Versionierungsstrategie. Das Ziel ist keine API, die bloß „funktioniert", sondern eine, die wartbar und vorhersehbar ist und der Clients vertrauen können.

In Ressourcen denken, nicht in Aktionen

Der Kern eines RESTful-Designs besteht darin, Ressourcen in deine URLs zu setzen, nicht Aktionen. Statt verblastiger Adressen wie /api/createPost benennst du die Ressource als Substantiv und überlässt der HTTP-Methode die Aktion:

  • GET /api/posts — auflisten
  • POST /api/posts — erstellen
  • GET /api/posts/{id} — einen Datensatz anzeigen
  • PUT/PATCH /api/posts/{id} — aktualisieren
  • DELETE /api/posts/{id} — löschen

Laravel unterstützt dieses Muster direkt. Die Definition Route::apiResource() erzeugt die fünf obigen Routen in einer einzigen Zeile; anders als das klassische resource in web.php überspringt sie die Routen create und edit, die Formulare anzeigen — denn eine API hat keine HTML-Formulare.

Routen mit einem Resource-Controller einrichten

Generiere zuerst einen Controller mit dem Flag --api:

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

Verdrahte ihn dann mit einer Zeile in routes/api.php:

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

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

Dies ordnet die Methoden index, store, show, update und destroy automatisch den passenden HTTP-Verben zu. Der Routenparameter {post} verwandelt sich, sofern typisiert, über Laravels Route Model Binding direkt in das zugehörige Post-Objekt; wird kein Datensatz gefunden, gibt Laravel von selbst einen 404 zurück:

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

JSON-Ausgabe mit API-Resources formen

Das Modell direkt mit return $post; zurückzugeben funktioniert, ist aber riskant: jede Datenbankspalte (interne Notizen, password, Zeitstempel) tritt unverändert nach außen, und der Client bricht bei jeder Schemaänderung. Verwende stattdessen eine API-Resource-Klasse — eine Transformationsschicht, in der du die JSON-Darstellung deines Modells explizit definierst.

php artisan make:resource PostResource

Anschließend entscheidest du, welche Felder nach außen gehen und unter welchen 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() fügt relationale Daten nur dann hinzu, wenn sie tatsächlich eager-geladen wurden — eine praktische Methode, um das N+1-Abfrageproblem zu vermeiden. Um eine Collection zurückzugeben, verwendest du PostResource::collection($posts). Möchtest du auch Metadaten wie die Gesamtseitenzahl zurückgeben, kannst du in index einen Paginator direkt an die Resource übergeben; Laravel erzeugt die Paginierungslinks automatisch unter links und meta.

Validierung und Fehlerantworten

Um eingehende Daten zu validieren, ohne den Controller aufzublähen, sind Form-Request-Klassen ideal:

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

Wenn du sie in der Controller-Methode typisierst, validiert Laravel die Anfrage automatisch; bei einem Regelverstoß erhält ein Client, der den Header Accept: application/json sendet, einen 422-Unprocessable-Content-Statuscode samt feldbezogener Fehlermeldungen. Das ist die Grundlage eines konsistenten Fehlervertrags in REST-APIs: 200/201 Erfolg, 401 Authentifizierung fehlt, 403 nicht autorisiert, 404 nicht gefunden, 422 Validierungsfehler. Diese Codes konsistent zu nutzen macht die Fehlerbehandlung auf Client-Seite vorhersehbar.

Versionierung: die API zukunftssicher machen

Sobald eine API veröffentlicht ist, wird es schwierig, sie zu ändern, ohne die Clients zu brechen, die sie nutzen. Die Antwort ist Versionierung. Die gängigste und expliziteste Methode ist, die Version in den URL-Pfad zu setzen:

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

So bleibt /api/v1/posts stabil; wenn schließlich eine inkompatible Änderung nötig wird, eröffnest du eine neue Version mit einem V2-Namespace und einem v2-Präfix und hältst die alte eine Zeit lang am Laufen. Controller in Versionsordner wie App\Http\Controllers\Api\V1 aufzuteilen hält auch die Codebasis physisch sauber. Alternativ kannst du die Version im Accept-Header tragen (Media-Type-Versionierung), aber der URL-basierte Ansatz ist praktischer — sowohl zum Testen im Browser als auch zum Nachverfolgen in Logs.

Authentifizierung und Rate Limiting

Zum Schutz nicht-öffentlicher Endpoints ist Laravels Sanctum-Paket die bevorzugte Lösung, sowohl für cookie-basierte SPA-Sitzungen als auch für tokenbasierten Zugriff. Geschützte Routen gruppierst du mit der auth:sanctum-Middleware:

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

Hier bleiben die Lese-Endpoints öffentlich, während die Schreib-Endpoints eine Authentifizierung erfordern. Es ist außerdem gute Praxis, mit der throttle-Middleware ein Rate Limit hinzuzufügen, um Missbrauch zu verhindern; Laravels RateLimiter erlaubt dir, die Anzahl der Anfragen pro Minute pro Benutzer oder pro IP zu definieren.

Häufige Fragen

Was ist der Unterschied zwischen apiResource und einem normalen resource?

Route::resource() erzeugt sieben Routen, von denen zwei (create, edit) dazu gedacht sind, HTML-Formulare anzuzeigen. Route::apiResource() überspringt diese beiden und lässt nur die fünf datenliefernden Routen übrig — genau das, was du in einer JSON-API ohne Formulardarstellung brauchst.

Warum eine API-Resource verwenden, statt das Modell direkt zurückzugeben?

Weil eine API-Resource deinen externen Vertrag von deinem Datenbankschema trennt. Selbst wenn du eine Spalte umbenennst oder ein sensibles Feld hinzufügst, ändert sich die ausgehende JSON nicht und sie leakt nicht, es sei denn, du entscheidest dich dafür. Das ist sowohl für die Sicherheit als auch für die Abwärtskompatibilität entscheidend.

Brauche ich Versionierung von Anfang an?

Für einen einzigen kleinen Client ist ein v1-Präfix nicht zwingend, doch die Kosten, es hinzuzufügen, sind nahezu null. Den Pfad von Tag eins an als /api/v1 festzulegen verschafft dir enorme Flexibilität, wenn später eine brechende Änderung nötig wird; es nachträglich hinzuzufügen erfordert, alle Clients zu migrieren.

Willst du ein solides Fundament für deine API? Ich helfe dir, eine skalierbare Laravel-REST-API zu entwerfen — von Resource-Controllern über Versionierung bis zur Authentifizierung. Kontaktiere mich und lass uns dein Projekt gemeinsam planen.

Devamı için