Olá, pessoal!
Estou de volta depois de algum tempo. Tinha planejado mostrar um pouco sobre os Controllers mas, estudando a documentação do Laravel 5.6, encontrei uma parte interessante para quem está montando API REST para os seus webservices e aplicações. São as API resources.
Os resources apareceram na documentação do Laravel a partir da versão 5.5. Eles 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?
P.s.: Confira todos os artigos anteriores, aqui, no meu perfil.
Então, para eu transformar o resource desta tabela, basta eu criar a classe através do artisan:
php artisan make:resource ProductResource
Sua classe ficará como esta:
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class ProductResource extends JsonResource { public function toArray($request) { return []; } }
Agora, é só adicionar as colunas que você quer retornar pela API Resource:
<?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, ]; } }
Parece simples até demais, mas é assim mesmo que funciona. Para finalizar, precisamos chamá-la em nossa rota ou Controller. Para isto, basta chamá-la estaticamente.
<?php use App\Product; use App\Http\Resources\ProductResource; Route::get('/products/{id}', function () { return new ProductResource(Product::find($id)); });
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 um Resource Collection
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 use App\Product; use App\Http\Resources\ProductResource; Route::get('/products/', function () { return ProductResource::collection(Product::al()); });
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 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', ], ]; } }
Não tem muito segredo, não é mesmo? Espero que tenham gostado e até a próxima.