Adicionando dados relacionados na API resource do Laravel

A API resource do Laravel facilitou bastante a comunicação RESTfull com outras plataformas. Como explicado no último artigo (API resources do Laravel, criando repostas RESTfull), onde iniciei sobre este tema, este recurso cria uma camada de transformação dos dados para trabalhar com JSON. Agora vou dar foco no relacionamento de dados, que não foi contemplado no último artigo.

Relacionamentos com API resource

Sempre que quisermos adicionar recursos relacionados de uma tabela, podemos retornar estes dados fazendo uma requisição no outro resource relacionado. Vamos ao nosso exemplo. Tenho a tabela product_line que possui diversos produtos. Para eu retornar todos os dados deste product_line e todos os produtos que pertencem a ele, basta eu adicionar a Collection de products em um atributo ‘products’ dentro do array.

[php]<?php

class ProductLineResource extends JsonResource
{
public function toArray($request)
{
return [
‘id’ => $this->id,
‘description’ => $this->description,
‘products’ => ProductResource::collection($this->products),
‘created_at’ => $this->created_at,
‘updated_at’ => $this->updated_at,
];
}
}

[/php]

Aqui… se o seu relacionamento está certinho na model a consulta já vai buscar os produtos relacionados a está linha de produtos. E retornar uma collection dentro do atributo ‘products’

Exibição Condicional

Além de trazer os relacionamentos também é possível ter o controle da resposta trazendo o dado relacionado apenas se ele já tiver sido carregado na model. Através da função whenLoaded podemos carregar apenas o relacionamento que queremos através do nome deste relacionamento. Assim, evita-se que sejam carregados relacionamentos desnecessários para o resource.

Agora vamos ao exemplo. Abaixo vamos trocar o relacionamento do $this->products para a função $this->whenLoaded(‘products’) para controlar o carregamento deste relacionamento

[php]<?php

class ProductLineResource extends JsonResource
{
public function toArray($request)
{
return [
‘id’ => $this->id,
‘description’ => $this->description,
‘products’ => ProductResource::collection($this->whenLoaded(‘products’)),
‘created_at’ => $this->created_at,
‘updated_at’ => $this->updated_at,
];
}
}
[/php]

No exemplo abaixo, se não for possível carregar o relacionamento do products o item será removido do resource.

Conclusão

Não existem segredos para a utilização dos relacionamentos dentro do API resource, na verdade todo o trabalho está por trás no Eloquent e na Model. Estando tudo certo por trás relacionar no API resource fica extremamente simples e natural. Para quem quiser se aprofundar mais nesta funcionalidade aconselho darem uma lida na documentação oficial.

API resources do Laravel, criando repostas RESTfull

Olá Pessoal, estou de volta depois de algum tempo. No último artigo eu aprofundei um pouco nos comandos do Eloquent. Tinha planejado para mostrar um pouco sobre os Controllers mas, estudando a documentação do Laravel 5.6 encontrei uma parte interessante para quem está montando API restfull para os seus webservices.  São as API resources. 

As API resources apareceram na documentação do Laravel a partir da versão 5.5. Elas funcionam como um camada de tratamento entre o Eloquent e as respostas JSON que são expostas pela API. Estas classes permitem que transformemos facilmente, models e collections em JSON.

Não é que este conceito seja completamente novo. O próprio Laravel, em versões anteriores, permite a utilização de transformers, com o Fractal, para fazer este tipo de trabalho. Mas, ao que parece, não é mais necessário instalar o módulo fractal para termos este funcionamento.

Criando um Resource

A classe resource é extremamente simples. Ela estende a classe JsonResource e implementa a função toArray(). Dentro desta função basta colocarmos os campos que queremos retornar na API e depois chamar a classe em sua controller ou rota.

Vamos ao nosso exemplo prático então… No começo desta série eu criei a tabela product, onde eu cadastrei meus produtos certo? (Confira todos os posts no fim deste artigo) Então para eu transformar o resource desta tabela basta eu criar a classe através do artisan:

[code]php artisan make:resource UserResource[/code]

Sua classe ficará como esta

[php]<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ProductResource extends JsonResource
{
public function toArray($request)
{
return [];
}
}[/php]

Agora é só adicionar as colunas que você quer retornar pela API Resource.

[php]<?php

class ProductResource extends JsonResource
{
public function toArray($request)
{
return [
‘id’ => $this->id,
‘product_line_id’ => $this->product_line_id,
‘description’ => $this->description,
‘expiration_date’ => $this->expiration_date,
‘price’ => $this->expiration_date,
];
}
}

[/php]

Parece simples até demais neh. Mas é assim mesmo que funciona. Para finalizar precisamos chamá-la em nossa rota ou Controller. Para isto basta chamá-la estaticamente.

[php]<?php

use App\Product;
use App\Http\Resources\ProductResource;

Route::get(‘/products/{id}’, function () {
return new ProductResource(Product::find($id));
});

[/php]

Neste exemplo coloquei dentro da própria rota. Mas, caso você queira fazer mais algum processo após receber seu novo JSON aconselho que mande isto para uma função na respectiva Controller. Assim, seu código ficará mais organizado.

Criando uma API Resource Collections

A classe Resource trabalha com um único model e o transforma em Array. A collection, por sua vez, trabalha com toda a coleção de dados da model. Mas não se espante, para utilizá-la é bem simples. Ao invés de instanciar o ProductResource, basta chamar o metodo collection estaticamente na rota ou controller.

[php]<?php

use App\Product;
use App\Http\Resources\ProductResource;

Route::get(‘/products/’, function () {
return ProductResource::collection(Product::all());
});

[/php]

Agora se quiser personalizar o retorno da Collection com alguns meta datas diferentes você pode criar uma classe separada para trabalhar em cima do Resource.

[php]<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ProductCollection extends ResourceCollection
{

public function toArray($request)
{
return [
‘data’ => $this->collection,
‘links’ => [
‘self’ => ‘link’,
],
];
}
}

[/php]

Concluindo

O Laravel nasceu com sua natureza e objetivos voltados para o paradigma do REST. A API Resources são a prova de como a comunidade Laravel está trabalhando para trazer formas otimizadas e simples no trabalho com APIs. Neste artigo apenas pincelei conceitos básicos da utilização desta funcionalidade, mas acredito que eu vá me aprofundar mais neste assunto. Espero que tenham gostado e até a próxima.