Come trasformare i modelli Eloquent in risposte JSON API coerenti. Dalla creazione delle classi resource ai campi condizionali fino all’integrazione con la paginazione.
Quando costruisci un’API, restituire direttamente i modelli Eloquent come JSON può esporre colonne che vorresti nascondere o inviare al client molti dati che non gli servono.Le Eloquent API Resource sono un livello di trasformazione tra il modello e la risposta JSON. Con il metodo toArray() definisci esplicitamente “cosa e in che formato” includere nella risposta.Vantaggi principali:
Controllo totale sui campi inclusi nella risposta
Un unico posto per rinominare campi e trasformare valori
Puoi mostrare o nascondere campi in base a condizioni
Puoi annidare le relazioni mantenendo una struttura coerente
Puoi restituire la resource da controller o route.
use App\Http\Resources\UserResource;use App\Models\User;Route::get('/users/{user}', function (User $user) { return new UserResource($user);});
In alternativa, usa il metodo toResource() del modello.
Route::get('/users/{user}', function (User $user) { return $user->toResource();});
toResource() cerca automaticamente la classe resource corrispondente (UserResource) in base al nome del modello.Di default la risposta è wrappata nella chiave data.
In toArray() puoi rinominare i campi e trasformare i valori.
public function toArray(Request $request): array{ return [ 'id' => $this->id, 'full_name' => $this->name, // Rinomina il campo 'email_address' => $this->email, // Rinomina il campo 'role' => strtoupper($this->role), // Trasforma il valore 'registered_at' => $this->created_at->toDateString(), // Formatta la data ];}
whenLoaded() — includere solo relazioni già caricate
Includendo la relazione solo se è già stata caricata con eager loading eviti il problema N+1 e crei risposte flessibili.
use App\Http\Resources\PostResource;public function toArray(Request $request): array{ return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, // Incluso solo se posts è stato caricato con with() 'posts' => PostResource::collection($this->whenLoaded('posts')), ];}
Nel controller decidi se caricare la relazione.
// Restituisce con i postsreturn new UserResource($user->load('posts'));// Restituisce senza postsreturn new UserResource($user);
Nelle risposte paginate, anche se hai chiamato withoutWrapping(), la chiave data viene sempre inclusa per coesistere con le chiavi meta e links della paginazione.