Adicionando dados relacionados na API resource do Laravel

Relacionamentos com API resource

Relacionamentos com API resource

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.

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

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.

Felipe Moraes
Felipe Moraes

Desde pequeno eu adorei tecnologia e este sentimento me fez estudar e trabalhar com desenvolvimento, design de interfaces e interação. Esta vontade de melhorar e aprender com a tecnologia me fez estar aqui na DialHost desde 2012.

API resources do Laravel, criando repostas RESTfull

Laravel API Resources

Laravel API Resources

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:

 

Sua classe ficará como esta

 

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

 

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.

 

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.

 

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.

 

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.

Felipe Moraes
Felipe Moraes

Desde pequeno eu adorei tecnologia e este sentimento me fez estudar e trabalhar com desenvolvimento, design de interfaces e interação. Esta vontade de melhorar e aprender com a tecnologia me fez estar aqui na DialHost desde 2012.

Aprofundando nas funções do Eloquent do Laravel

Aprofundando no Eloquent do Laravel

Aprofundando no Eloquent do Laravel

No artigo anterior, eu falei sobre o Eloquent e como ele pode simplificar o trabalho das models com os bancos de dados. Para este artigo deixei algumas funções que achei realmente diferenciadas para aprofundar neste segundo artigo. Então vamos lá!

findOrFail no Eloquent

A função findOrFail trata exceções nas buscas do banco de dados. No exemplo do artigo passado ao fazermos uma busca pelo id do produto, utilizando o findOFail($id), ele retornaria uma coleção com os resultados da busca ou dispararia um erro 404 se nenhum resultado fosse encontrado.

Ele é um método bem útil para tratarmos os resultados de Rotas ou Controllers que necessitam do resultado desta busca para funcionar.

 

firstOrFail

Este método do Eloquent é semelhante ao findOrFail. Porém, ele limitará a busca apenas ao primeiro resultado obtido.

Este método firstOrFail é útil para fazer uma busca mais ampla e mesmo assim trazer apenas um resultado.

 

Otimizando o uso de memória com Chunk e Cursor do Eloquent

Ao fazer buscas podemos nos deparar com resultados gigantescos dependendo da tabela que consultamos. Estas consultas podem demorar para trazer um retorno e consumir muita memória. Para resolver este problema o Eloquent possui a função chunk que faz a quebra desta consulta em pedaços menores. Assim, o PHP processará centenas de milhares de registros sem estourar o seu uso de memória.

 

No exemplo acima, temos dois parâmetros sendo passados. O primeiro é o limite de resultados que cada bloco irá trabalhar. O segundo é o que será executado para cada resultado de cada bloco da consulta. Podemos dizer que ele otimiza a consulta colocando um limite de resultados e fazendo um foreach automático até que todos os resultados da consulta sejam processados.

Ainda para otimização de buscas temos o método cursor. Ele tem uma aplicação semelhante. Neste caso, porém, ele trabalhará com apenas uma query. A otimização aqui fica por conta do retorno que a função cursor tem. Ela retornará um Generator.

Um generator permite que escrevamos um código que utiliza foreach para interagir com um conjunto de informações sem precisar de registrar um array na memória. Assim, diminui-se o risco risco de estourarmos a memória em um processamento grande de dados.

No caso para usar esta função fazemos como abaixo:

 

Mass Update com Eloquent

No último artigo eu mostrei como fazer um update de um registro em específico. Mas, podemos atualizar diversos registros que contemplam uma condição passada. Para isso usamo o comando update do Eloquent. Com esta função o Eloquent atualizará o campo passado em todos os resultados da busca que você fizer antes.

 

firstOrCreate

O firstOrCreate fará a criação de um registro, mas primeiro ele validará se o registro já existe no banco. Se o registro já existir teremos apenas o retorno do mesmo. Senão, ele criará o registro. Como fica claro, este comando só será útil para realizar a criação de dados únicos. No nosso exemplo isto seria interessante para o product line, já que não quero que existam mais de um linha de produtos com o mesmo nome.

 

firstOrNew

Assim como o firstOrCreate o firstOrNew do Eloquent tentará encontrar um registro já existente do parâmetro que passarmos. A diferença é que ele não salvará o registro no banco de dados, mas sim, instanciará um novo model com este registro. Assim, para salvar realmente no banco será necessário executar o comando “save”.

 

updateOrCreate

Mais uma vez, a função updateOrCreate irá buscar um registro existente do parâmetro que passamos. Mas, como diz o nome da função aqui ele vai atualizar o valor ou criar o novo registro no banco de dados. Esta função se torna útil para uma edição forçada onde mesmo que o registro exista eu queira atualizar um parâmetro vinculado a ele.

 

Aqui, o primeiro parâmetro será o campo que iremos fazer a busca. Caso a consulta retorne um valor o sistema irá atualizar o campo abbreviation. Caso não encontre, o mesmo irá criar um registro novo com a description “Kilogramas” e setará a abbreviation  como “Kg”.

SoftDelete com Eloquent

O Eloquent do Laravel permite o sistema trabalhar com a metodologia de Soft Delete. No Soft Delete seus dados não serão deletados realmente, eles apenas terão setados um campo deleted_at sempre que for executada uma ação de delete().

Para isto funcionar primeiramente temos que setar em nossa migration schema o campo softDeletes.

Lembra do código abaixo?(se não lembra é só conferir o post Criando migrations com o Laravel 5.5) Então eu adicionei ao final o campo softDeletes.

 

Agora precisamos setar nossa model para trabalhar com softDelete. Para isto chamaremos a classe  SoftDeletes para usarmos, e criaremos uma variável $dates

 

Com tudo isto configurado, agora toda vez que executar a função delete() do Eloquent a mesma irá definir a coluna deleted_at com a data e hora do momento da exclusão.

Por fim, caso queira restaurar este dado, ficou bem fácil. Podemos executar a função restore() do Eloquent  como abaixo.

 

Conclusão

O Eloquent tem diversas funções para facilitar e diminuir o seu trabalho com aquelas tarefas usuais de banco de dados. Apenas com estes dois artigos que compartilhei com você deu para ter apenas uma visão básica das diversas situações que ele pode resolver.

Para quem quiser aprofundar mais nesta questão e tiver habilidades com o inglês fica a dica de dar uma lida na documentação completa do Laravel.

Felipe Moraes
Felipe Moraes

Desde pequeno eu adorei tecnologia e este sentimento me fez estudar e trabalhar com desenvolvimento, design de interfaces e interação. Esta vontade de melhorar e aprender com a tecnologia me fez estar aqui na DialHost desde 2012.

Eloquent, simplificando as Models no Laravel

Eloquent no Laravel

Eloquent no Laravel

Hoje retomo a série de Artigos sobre o Laravel trazendo o Eloquent, uma forma simples de trabalhar com consultas a bancos de dados e desenvolver suas Models.

No último artigo, abordei a criação das migrations e, como o Laravel pode relacionar as tabelas para você. Lembra do exemplo da tabela de produtos que eu criei? Então… Agora é hora de começar a buscar estes dados para a nossa aplicação. Para isto precisaremos criar Eloquent Models.

Models

As Models, dentro da arquitetura MVC, são classes responsáveis pela leitura, escrita e validação  de qualquer dado. Por isto, será aqui que iremos trabalhar com Eloquent para fazermos todo tipo de ações no nosso banco de dados. Mas, primeiro vamos entender o que é o Eloquent.

Eloquent no Laravel

O Eloquent nada mais é que um ORM que vem em conjunto com o Laravel. Mas, melhor que isso, ele possui uma estrutura bem simples para você realizar a implementação da sua lógica de controle com banco de dados.

Com base nos preceitos do ORM (Object relational mapping) Eloquent abstrai toda a complexidade da interação com os bancos de dados utilizando as Models para interagir com cada tabela.

Para facilitar o trabalho com ele existem algumas convenções como:

  • Os nomes de tabelas são padronizadas para o plural da classe que irá consumí-la.
  • As Primary keys são sempre vinculadas à uma coluna id.
  • Toda tabela possuirá colunas timestamp mostrando a data de criação (created_at) e data de atualização (updated_at).
  • Por padrão, as Models do Eloquent irão buscar as configurações de conexão com o banco de dados no arquivo padrão do Laravel, “config/database.php”.

Resumidamente falando, ele consegue trazer em uma ou duas linhas o que você gastaria muitas linhas de comando para executar.

Criando as Models com Eloquent

Saindo um pouco da teoria, vamos voltar ao nosso exemplo. Precisamos criar as Models que irão trabalhar com as tabelas “product_lines” e “products”. Para isto vou abrir o terminal da minha Hospedagem Cloud que possuo aqui na DialHost e digitar o seguinte comando:

 

Ao executar estes comandos vamos poder observar que as novas classes foi criada dentro da pasta app.

product_line.php

product.php

 

Para um sistema de consultas básico nem é necessário implementar funções dentro destas classes. Isto porque o próprio “Eloquent Model” já implementa diversas funções de consultas e manipulação de dados com o banco. Com a classe referenciada vou apenas chamar as funções do Eloquent diretamente através da Controller.

Principais Funções do Eloquent

Consultas

 

Para estas duas últimas funções, aconselho que sejam criadas funções dentro da Model que as executem. Assim, podemos abstrair a regra de consulta das Controllers. Esta forma é uma boa prática , principalmente se temos uma query complexa que exija muitos wheres e etc.

Você ainda pode utilizar de funções agregadoras como count, sum, avg, max, min.

 

Inserindo dados com Eloquent

Para inserir dados com o Eloquent existem 2 formas. Na primeira, você instancia a Model em uma variável, dentro da Controller, seta os atributos e então salva tudo no final.

 

Eu particularmente achei mais direta e limpa a forma a seguir. Ela é denomiada como Mass Assignment. Aqui eu chamo uma função estática que cria o registro passando os atributos como array

 

Para fazer a inserção desta segunda forma você precisa setar na sua Model os campos que serão permitidos serem setados. Por se tratar de uma inserção em massa o Laravel bloqueia todos os campos por padrão. Isto é para evitar que usuários consigam passar parâmetros indesejados na Request e que eles acabem alterando um dado importante dentro do banco de dados.

Então criarei na Model Product a variavel “fillable” e definirei um array com os campos que serão inseridos aqui.

Atualizando dados com Eloquent

A forma mais convencional de atualizar um dado através do Eloquent é semelhante a inserir um dado. A diferença é que já teremos a instância do produto especifico que iremos editar e então salvar o novo valor.

 

Removendo dados com Eloquent

Remover um dado com Eloquent é ainda mais fácil basta setarmos na função o comando delete() na instância que estamos trabalhando.

Conclusão

É claro que na vida real ainda teremos que fazer validações para deletar o registro apenas se ele realmente existir no banco. Ou durante uma edição verificar se o dado já existe antes de atualizá-lo e senão perguntar se o usuário deseja criar.

Apenas lendo por alto o Eloquent já  pensei em um novo post com algumas funções que não deu para explanar aqui. Se fosse a fundo nestas funções este artigo ficaria muito extenso e cansativo. então aguardem até o próximo post onde eu irei falar um pouco sobre funções específicas de busca, updates, criação e remoção de dados.

Felipe Moraes
Felipe Moraes

Desde pequeno eu adorei tecnologia e este sentimento me fez estudar e trabalhar com desenvolvimento, design de interfaces e interação. Esta vontade de melhorar e aprender com a tecnologia me fez estar aqui na DialHost desde 2012.

Criando Migrations com Laravel 5.5

Criação das migrations e relacionamento de tabelas no Laravel

Criação das migrations e relacionamento de tabelas no Laravel

Quando nossa equipe inicia um determinado projeto, costumamos reunir para discutir sobre a estrutura do banco de dados, como as regras de negócio serão implementadas e os dados serão gravados para tudo funcionar o mais perfeito possível. Desta discussão, já montamos o primeiro modelo de relacionamentos das tabelas no banco de dados. Costuma ser um modelo rápido feito no WorkBench.

Acredito que este processo seja parecido em diversas empresas de desenvolvimento, quando estão iniciando um projeto. Agora apresento algumas facilidades e seguranças que os Migrations do Laravel implementam para a montagem da estrutura do seu banco de dados, assim como seu relacionamento como um todo.

Como exemplo prático, montei este banco que simula o catálogo de produtos de uma loja. Este banco possui os produtos e seu relacionamento com a linha de produtos.

Modelo de banco de dados de produtos para exemplo de migration.

Criando as Migrations

O conceito de migrations trazido pelo Laravel permite o controle de versões e assim facilitar a modificação e compartilhamento da estrutura do banco de dados entre equipes. Imagine você mexendo em um projeto, em seu ambiente de desenvolvimento. Você cria uma nova coluna em seu banco de dados e continua desenvolvendo seu código normalmente. Sem as migrations seu colega pega seu código coloca no ambiente de desenvolvimento dele e tenta rodar. É claro que teremos diversos erros disparando na tela deste cara.

Agora com as migrations seu colega de trabalho verá nos registros de versionamento do código que teve uma atualização de arquivos na pasta “migrations” e então basta ele rodar o comando php artisan migrate que seu banco estará totalmente atualizado.

Para criar uma migration, durante o desenvolvimento do código é importante que tenhamos uma configuração de banco de dados. Afinal no fim das contas as migrations irão produzir um banco de dados.

Para configurá-lo basta setar as configurações do banco de dados, criado em seu servidor, dentro do arquivo .env que fica na raiz do projeto.

 

Ahhh, quase ia me esquecendo! Se você chegou aqui mas está perdido em como instalar o Laravel, tenho o primeiro artigo desta série.

Tudo configurado, agora vamos gerar nossas novas classes de migrations. Isto tudo será feito através do comando artisan make:migration.

Ao final de cada comando, vocês podem ver que adicionei a opção –create. Esta opção permite que eu defina o nome da tabela que eu estou criando. Existem outras opções para este comando que vocês podem ver na documentação completa do Laravel 5.5.

A estrutura da migration é simples. Ela importa as classes Schema, Blueprint e Migration  e possui 2 funções:

UP

Esta função é a responsável pela implementação das atualizações do banco. criar uma tabela, atualizar uma coluna e etc.

Down

É a função que fará exatamente o inverso da função UP revertendo seu banco de dados ao estado anterior a esta atualização.

Então, minhas classes ficaram desta forma.

create_product 

 

create_product_line 

 

Acima você vai ver que existe uma definição que não estava em meu diagrama. $table->timestamps(); Isto é um padrão do Eloquent do Laravel para controlar quando um dado é criado e atualizado.

Outra definição do diagrama porém, não foi incluída de propósito.  Fiz isto para chegar finalmente ao objetivo deste post. Os relacionamentos entre as tabelas.

Relacionando tabelas

Com as migrations é possível criar foreign keys e definir o relacionamento entre as tabelas do seu banco de dados. Este relacionamento cria restrições que protegem a integridade dos dados suas tabelas.

Para criar este relacionamento é bem simples.  Voltemos ao nosso exemplo no arquivo create_product 

 

Traduzindo a linha nova, temos uma Foreign key que referencia à coluna “id” na tabela “product_line”.

Além disto é possível adicionar restrições para qualquer ação de atualização (onUpdate) e exclusão (onDelete) de registros dentro da tabela.  Neste caso tratarei para que sempre que houver a exclusão de uma linha de produtos este perca a referência com a tabela product_line (Setar como nulo).

Desta forma eu permito que uma linha de produto seja excluído. Claro que aqui o produto ficará orfão de uma linha de produto. Mas, por enquanto estamos apenas trabalhando as regras do banco.

Removendo um relacionamento

Apenas para concluir… Se quiser remover o relacionamento criado isto é possível utilizando o método dropForeign.

Agora que as migrations estão completas o próximo passo será definir as Models. Mas, este fica pro próximo artigo. 🙂

Felipe Moraes
Felipe Moraes

Desde pequeno eu adorei tecnologia e este sentimento me fez estudar e trabalhar com desenvolvimento, design de interfaces e interação. Esta vontade de melhorar e aprender com a tecnologia me fez estar aqui na DialHost desde 2012.