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.