API resource class: bridge between the model and JSON API
brief introduction
Generate resource class
php artisan make:resource UserResource
php artisan make:resource Users --collection php artisan make:resource UserCollection
Core concepts
Note: This is a high-level overview of resources and resource collections. It is strongly recommended that you read other parts of this document to further enhance your understanding of the functions and customization provided by resource classes.
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\Resource; class UserResource extends Resource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; } }
use App\User; use App\Http\Resources\UserResource; Route::get('/user', function () { return new UserResource(User::find(1)); });
Resource Collection
use App\User; use App\Http\Resources\UserResource; Route::get('/user', function () { return UserResource::collection(User::all()); });
php artisan make:resource UserCollection
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection { /** * Transform the resource collection into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'data' => $this->collection, 'links' => [ 'self' => 'link-value', ], ]; } }
use App\User; use App\Http\Resources\UserCollection; Route::get('/users', function () { return new UserCollection(User::all()); });
Write resource class
Note: If you haven't read Core concepts It is strongly recommended that you read that part of the document before continuing.
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\Resource; class UserResource extends Resource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; } }
use App\User; use App\Http\Resources\UserResource; Route::get('/user', function () { return new UserResource(User::find(1)); });
/** *Convert resources to arrays * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'posts' => Post::collection($this->posts), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
Note: If you want to include association relationships only after they are loaded, please refer to the association relationship part of the attached conditions.
use App\User; use App\Http\Resources\UserResource; Route::get('/user', function () { return UserResource::collection(User::all()); });
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection { /** * Transform the resource collection into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'data' => $this->collection, 'links' => [ 'self' => 'link-value', ], ]; } }
use App\User; use App\Http\Resources\UserCollection; Route::get('/users', function () { return new UserCollection(User::all()); });
Data packaging
{ "data": [ { "id": 1, "name": "Eladio Schroeder Sr.", "email": " therese28@example.com ", }, { "id": 2, "name": "Liliana Mayert", "email": " evandervort@example.com ", } ] }
<? php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Http\Resources\Json\Resource; class AppServiceProvider extends ServiceProvider { /** * Perform post-registration booting of services. * * @return void */ public function boot() { Resource::withoutWrapping(); } /** * Register bindings in the container. * * @return void */ public function register() { // } }
Note:
withoutWrapping It only affects the outermost resources, and does not remove the
data Key.
Wrapping nested resources
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class CommentsCollection extends ResourceCollection { /** * Transform the resource collection into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return ['data' => $this->collection]; } }
Data Packaging and Paging
{ "data": [ { "id": 1, "name": "Eladio Schroeder Sr.", "email": " therese28@example.com ", }, { "id": 2, "name": "Liliana Mayert", "email": " evandervort@example.com ", } ], "links":{ "first": " http://example.com/pagination?page=1 ", "last": " http://example.com/pagination?page=1 ", "prev": null, "next": null }, "meta":{ "current_page": 1, "from": 1, "last_page": 1, "path": " http://example.com/pagination ", "per_page": 15, "to": 10, "total": 10 } }
paging
use App\User; use App\Http\Resources\UserCollection; Route::get('/users', function () { return new UserCollection(User::paginate()); });
{ "data": [ { "id": 1, "name": "Eladio Schroeder Sr.", "email": " therese28@example.com ", }, { "id": 2, "name": "Liliana Mayert", "email": " evandervort@example.com ", } ], "links":{ "first": " http://example.com/pagination?page=1 ", "last": " http://example.com/pagination?page=1 ", "prev": null, "next": null }, "meta":{ "current_page": 1, "from": 1, "last_page": 1, "path": " http://example.com/pagination ", "per_page": 15, "to": 10, "total": 10 } }
Conditional attribute
/** *Convert resources to arrays * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'secret' => $this->when($this->isAdmin(), 'secret-value'), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
'secret' => $this->when($this->isAdmin(), function () { return 'secret-value'; }),
Note: Remember that method calls on resource classes actually proxy underlying model instance methods, so in this example,
isAdmin The actual underlying layer of method invocation
User Methods on the model.
/** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, $this->mergeWhen($this->isAdmin(), [ 'first-secret' => 'value', 'second-secret' => 'value', ]), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
Note:
mergeWhen Method cannot be used in an array of mixed strings and numeric keys. In addition, it cannot be used in an array of pure numeric keys without sequential sorting.
Conditional association
/** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'posts' => Post::collection($this->whenLoaded('posts')), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }
/** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'expires_at' => $this->whenPivotLoaded('role_users', function () { return $this->pivot->expires_at; }), ]; }
Add Metadata
/** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'data' => $this->collection, 'links' => [ 'self' => 'link-value', ], ]; }
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UserCollection extends ResourceCollection { /** * Transform the resource collection into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return parent::toArray($request); } /** * Get additional data that should be returned with the resource array. * * @param \Illuminate\Http\Request $request * @return array */ public function with($request) { return [ 'meta' => [ 'key' => 'value', ], ]; } }
return (new UserCollection(User::all()->load('roles'))) ->additional(['meta' => [ 'key' => 'value', ]]);
Resource response
use App\User; use App\Http\Resources\UserResource; Route::get('/user', function () { return new UserResource(User::find(1)); });
use App\User; use App\Http\Resources\UserResource; Route::get('/user', function () { return (new UserResource(User::find(1))) ->response() ->header('X-Value', 'True'); });
<? php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\Resource; class UserResource extends Resource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, ]; } /** * Customize the outgoing response for the resource. * * @param \Illuminate\Http\Request * @param \Illuminate\Http\Response * @return void */ public function withResponse($request, $response) { $response->header('X-Value', 'True'); } }