How nice Eloquent API Resources, added to Laravel 5.5
Tags: laravel, api, showdev
Published: 2018-04-09 16:28:15

---
title: How nice Eloquent API Resources, added to Laravel 5.5
published: true
description: 
tags: laravel, api, showdev
---

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
<?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();
    }
}
```

(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:

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

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.

![](https://thepracticaldev.s3.amazonaws.com/i/au60qh8hc2afux49sx62.jpg)

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
<?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),
        ];
    }
}
```

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
<?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()
        );
    }
}
```

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.