DEV Community

Kay Gosho
Kay Gosho

Posted on

How nice Eloquent API Resources, added to Laravel 5.5

This is a little bit late article, but I found Laravel 5.5's Eloquent API Resources really nice feature.

When to use Eloquent API Resources

When we create a basic REST API with Laravel, the simpliest code would be like this:

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller as BaseController;
use App\Company;

class CompanyController extends BaseController
{
    public function index()
    {
        return Company::all();
    }
}
Enter fullscreen mode Exit fullscreen mode

(We assume Company the main domain Actor here)

Laravel returns Company::all() as an arrays of Company.

But we sometimes need to return more complex data.

Imagine the Company has a lot of attributes, and you should change formats based on the request.

For example, Company has some sensitive info like phone_number, and only admin user can view them.

Maybe we should write a logic to determine requests like this:

    public function index(Request $request)
    {
        return Company::all()->map(function ($company) use ($request) {
            if (! $request->user->is_admin) {
                unset($company['phone_number']);
            }
        });
    }
Enter fullscreen mode Exit fullscreen mode

Or, we might add phone_number to hidden attributes in Company model.
Whichever you do, you should define some logic in Controller with procedural way.

The above example is still easier. In the real world project, we should return more complex data. (Diff time, include other relations, combine strings, ...)

This is where Eloquent API Resources comes into play.

Transformation Layer

When we need a complex data structure, or even simple data structure, "Transformation Layer" is useful.

This layer simply receive data and returns an array.

Its merit is:

  • Keep controller simple
  • Reduce logics with its helpers
  • Easy to understand the data structure API server returns

I think the last one is really important.
Without this layer, we should check Eloquent model or table definition, $append attributes, or controller procedure.

(If your team creates complete up-to-date API documentation, you can refer it. But in a lot of projects you can no time to write it...!)

Replace the code

In the above example, we write transformation logic in Controller. Let's move the logic to CompanyResource.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class CompanyResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'phone_number' => $this->when($request->user->is_admin, $this->phone_number),
        ];
    }
}
Enter fullscreen mode Exit fullscreen mode

Here, we would find the structure became clearer. Even frontend engineer can easily find what/when returns attributes.

Let's use it In the controller.

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller as BaseController;
use App\Company;
use App\Http\Resources\CompanyResource;

class CompanyController extends BaseController
{
    public function index()
    {
        return CompanyResource::collection(
            Company::all()
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

The Controller became very simple, delegating transformation logic to CompanyResource.

when is provided by Eloquent Resource. Simple but powerful helper, cause it allows us to write declarative code.

You can use a lot of Eloquent Resource's useful features. Check the official document for more info.

https://laravel.com/docs/5.5/eloquent-resources

BTW, Laravel's documentation is really awesome, we can find almost everything we need there.

Fractal for Larave ~5.4

If you are using Laravel ~5.4, I recommend to use Fractal.

It is a great library for "Transformation Layer", and provides Laravel wrapper.

https://github.com/spatie/laravel-fractal

Note: You can use Fractal even in 5.5. It has lots of features.

Furthermore

You may remember GraphQL. It enables us to build API server much fluent way than REST.

We can use GraphQL with the following library.

https://github.com/Folkloreatelier/laravel-graphql

I haven't tried it yet so I will check soon.

Top comments (0)