Easy JSON API Responses with Laravel
Laravel has evolved so much since I last laid hands on in over a year-and-a-half ago. Eloquent API Resources are a massive boost to those of us looking to easily hammer out standardized JSON API responses. While these are not fully-spec compliant {json:api} responses, they're pretty darn close and good enough for most use cases.
Simply put, an API Resource consumes a database query in the form of a model and spits out structured JSON. In the usual Laravel way, API Resources are easily customized.
Heads up: this is based on Laravel 8.x. and may not work in previous versions.
Create a Resource for a Single Object
So, let's say I want to query a single user. First I'll start by using artistan to create the Resource class file.
php artisan make:resource UserResource
Then in the toArray($request)
method, I'll return an array of what I want to expose to the API consumer. This is great, as I can abstract the model properties away from the response and do some basic serialization before responding, if desired.
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
Now I can simply return the Resource from the controller. By default, the array will be wrapped in a data
key. I recommend leaving this setting as is but it can be overridden as per the documentation.
use App\Http\Resources\UserCollection;
use App\Models\User;
Route::get('/users', function () {
return new UserCollection(User::all());
});
The object returned will look similar to the following.
{
data: {
id: 1,
name: 'Luke Skywalker',
email: 'l.skywalker@jedi.org',
created_at: 'timestamp',
updated_at: 'timestamp'
}
}
Return a Collection
The JsonResource
class has a static collection
method to return an array of Resources, or in my case, Users. This is so dang easy I want to weep for joy.
use App\Http\Resources\UserResource;
use App\Models\User;
Route::get('/users', function () {
return UserResource::collection(User::all());
});
This returns an array of Users in the data
key.
{
data: [
{
id: 1,
name: 'Luke Skywalker',
email: 'l.skywalker@jedi.org',
created_at: 'timestamp',
updated_at: 'timestamp'
},
{
id: 2,
name: 'Leia Organa',
email: 'l.organa@rebelalliance.org',
created_at: 'timestamp',
updated_at: 'timestamp'
},
...
]
}
More complex customizations can be done by creating a UserCollection
resource, which Laravel is smart enough to proxy to a collection of UserResource
instances.
Other Goodies
Eloquent API Resources also makes these features seem a breeze to implement:
View the full documentation for the full details of Eloquent API Resources.