Erläutert, wie Sie Eloquent-Modelle in konsistente JSON-API-Antworten überführen. Von der Erstellung einer Resource-Klasse über bedingte Felder bis zur Zusammenarbeit mit Paginierung.
Beim Aufbau einer API führt das direkte Ausliefern von Eloquent-Modellen als JSON schnell dazu, dass sensible Spalten mitversendet werden oder unnötig viele Daten an den Client gehen.Eloquent-API-Ressourcen bilden eine Transformationsschicht zwischen Model und JSON-Antwort. In der Methode toArray() legen Sie explizit fest, welche Informationen in welcher Form in die Antwort einfließen.Die Vorteile im Überblick:
Volle Kontrolle darüber, welche Felder in der Antwort erscheinen
Feldumbenennung und Werttransformation an einem Ort gebündelt
Felder lassen sich bedingt ein- oder ausblenden
Relationen können verschachtelt werden, um eine konsistente Struktur zu wahren
Definierte Resources können aus einem Controller oder einer Route zurückgegeben werden.
use App\Http\Resources\UserResource;use App\Models\User;Route::get('/users/{user}', function (User $user) { return new UserResource($user);});
Alternativ verwenden Sie die Methode toResource() des Modells.
Route::get('/users/{user}', function (User $user) { return $user->toResource();});
toResource() sucht anhand des Modellnamens automatisch die passende Resource-Klasse (UserResource).Standardmäßig wird die Antwort in einen Schlüssel data verpackt.
Indem Sie Relationen nur bei bereits geladenem Eager Loading einbinden, vermeiden Sie das N+1-Problem und behalten die Struktur flexibel.
use App\Http\Resources\PostResource;public function toArray(Request $request): array{ return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, // Nur einbinden, wenn posts mit with() geladen wurden 'posts' => PostResource::collection($this->whenLoaded('posts')), ];}
Ob die Relation geladen wird, steuert der Controller.
// Antwort inklusive postsreturn new UserResource($user->load('posts'));// Antwort ohne postsreturn new UserResource($user);
Bei Paginierungs-Antworten wird der Schlüssel data immer beibehalten – auch wenn Sie withoutWrapping() aufgerufen haben. Nur so lassen sich die Schlüssel meta und links sauber daneben ausliefern.
Standardmäßig wird die äußerste Resource in einen Schlüssel data verpackt. Deaktivieren Sie dieses Verhalten mit withoutWrapping() in der boot()-Methode Ihres AppServiceProvider.
use Illuminate\Http\Resources\Json\JsonResource;public function boot(): void{ JsonResource::withoutWrapping();}
withoutWrapping() wirkt sich nur auf das äußerste Wrapping aus. Ein von Ihnen selbst definierter data-Schlüssel bleibt erhalten.