PHP

Como melhorar o retorno das suas APIs no Laravel com API Resource do Eloquent

Um dos pontos mais importantes quando estamos trabalhando APIs é o retorno dos dados. Veja como melhorar suas APIs no Laravel usando o API Resouce do Eloquent.

há 5 anos 3 semanas

Formação Desenvolvedor PHP
Conheça a formação em detalhes

Quando estamos construindo uma API, alguns pontos são extremamente importantes para que o cliente consiga consumir corretamente as informações. Um desses pontos é o modo como retornamos dados da nossa API.

Em aplicações web existe uma preocupação muito grande com a aparência e usabilidade na hora de mostrar as informações. Quando estamos trabalhando com APIs nossa preocupação não deve ser diretamente ligada a esses detalhes, porém precisamos cuidar de outras características para que os clientes da nossa API consigam utilizá-la de maneira correta. Um desses cuidados deve ser a estrutura que as informações são retornadas.

Como os dados são transferidos em uma API

Geralmente as APIs são utilizadas para integração entre sistemas diferentes. Esses sistemas podem apresentar arquiteturas completamente distintas, por esse motivo os dados são transferidos para um formato intermediário conhecido tanto pela API quanto pelo cliente. Os formatos mais utilizados são JSON, XML e YAML.

O processo de transformação dos dados para esse formato intermediário normalmente é chamado de serialização. No Laravel temos recursos bem importantes para serialização, aconselho a leitura do artigo onde falamos o que é e como utilizar serialização JSON no Laravel. O grande detalhe é que mesmo com os recursos específicos que a serialização possui ele não permite personalizar totalmente a resposta, nesse ponto entra o API Resource.

Laravel - Eloquent ORM
Curso Laravel - Eloquent ORM
Conhecer o curso

O que é API Resource

O API Resource é uma camada extra que usamos na API para transformar os dados que vamos enviar ao cliente. Ela permite que a estrutura de retorno seja totalmente personalizada, isso nos permite formatar os dados na melhor maneira para entregar ao cliente. Além de garantir o desacoplamento com o model, uma vez que podemos definir a estrutura de forma separada. O conceito da camada de transformação não é exclusividade do Laravel. Inclusive no próprio PHP temos algumas outras bibliotecas que facilitam esse trabalho, uma das mais conhecidas é o Fractal. O API Resource do Laravel facilita bastante a vida quando estamos dentro do Framework, mas também é possível utilizar qualquer outra biblioteca.

Resource

O primeiro conceito que precisamos conhecer é o resource. Ele é uma classe que usamos para transformar um único item de um recurso. Falando assim parece um pouco complicado, mas na prática o que ele faz é pegar um item que precisamos converter e transformar para o formato especificado nele. Vamos imaginar que estamos buscando o produto Iphone X no banco de dados e precisamos devolver ele na API com uma formatação específica, é basicamente isso que o Resource faz.

A classe do resource deve possuir um método chamado toArray, esse método precisa retornar um array com os dados que deseja que o recurso possua após a conversão. O Laravel injeta automaticamente as propriedades do nosso model no resource, isso nos permite acessá-las através do escopo this. Veja o exemplo abaixo:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ProductResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'codigo' => $this->id,
            'nome'   => $this->name,
            'preco'  => $this->price,
        ];
    }
}

Basicamente o que estamos fazendo é pegar os dados vindos do model (id, name e price) e colocando respectivamente nos itens do array (código, nome e preço).

O modo como usamos o resource é extremamente simples, basta passarmos 1 item do model no construtor da classe:

new App\Http\Resources\ProductResource(App\Product::find(10));

A instância acima pode ser retornada diretamente em uma action do controller ou em uma rota que utiliza função anônima.

A classe acima parece não fazer muito sentido olhando à primeira vista, porém ganhamos algumas vantagens imprescindíveis em usar essa camada:

  • Liberdade para definição da estrutura
  • Possibilidade de enviar dados extras, como, relações ou gerados através de outros métodos da aplicação
  • Podemos alterar o nome das propriedades do nosso model sem problemas, pois agora definimos o nome que será retornado ao usuário diretamente na estrutura;
  • O nosso model não está preso a somente um modo de exibição, caso necessário podemos criar várias classes de Resource para o mesmo model.

Silex - Framework PHP
Curso Silex - Framework PHP
Conhecer o curso

Resource Collection

A classe que vimos acima é usada para conversão de apenas um item do model. É comum, porém, precisamos retornar uma coleção de itens na nossa API. Nesse caso utilizamos o Resource Collection. Ele é muito útil para retornar meta informações sobre o conjunto de dados que estamos retornando. Nele também usamos o método toArray para montar o retorno da nossa aplicação. E usamos a propriedade collection para retornar as informações da coleção:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ProductCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'links' => [
                'self' => 'link-value',
            ],
        ];
    }
}

O modo de usar é basicamente igual ao Resource, porém precisamos passar um conjunto de informações:

new App\Http\Resources\ProductCollection(App\Product::all());

Os dados buscados no banco serão colocados dentro da chave data do nosso resultado. O Laravel automaticamente utiliza o Resource específico para converter cada item da coleção com base na convenção do nome, com isso terá a estrutura definida tanto para cada item específico da coleção como da estrutura geral de retorno.

Conclusão

O modo como retornamos as informações na nossa API é um dos itens mais importantes. Isso juntamente com o uso correto e semântico HTTP dos verbos na requisição e dos códigos na resposta são os itens onde os desenvolvedores mais pecam e que precisa de atenção no desenvolvimento de APIs. Não deixe também de explorar um pouco a documentação do API Resouce no site do Laravel, ele possui recursos para ajudar com relações, meta informações, personalização da resposta HTTP entre outros.

Já leu nossos artigos sobre o ecossistema Laravel e Eloquent? Veja como usar escopos do Eloquent para construir consultas mais limpas no Laravel, como remover a lógica das views com presenters no Laravel e como aliviar seus controllers com os eventos do Eloquent no Laravel, tudo aqui no blog da Treina Web.

Autor(a) do artigo

Elton Fonseca
Elton Fonseca

Professor e desenvolvedor. Formado em análise e desenvolvimento de sistema, pós graduado em engenharia e arquitetura de software. É autor de cursos em diversos temas, como, desenvolvimento back-end, cloud computing e CMSs. Nas horas vagas adora estudar sobre o mercado financeiro, cozinhar e brincar com pequeno Daniel. @eltonfonsecadev

Todos os artigos

Artigos relacionados Ver todos