Como usar o padrão de repositório em um aplicativo Laravel
Tempo de leitura: 6 minutos
Um repositório pode ser definido como uma camada de abstração entre o domínio e as camadas de mapeamento de dados, uma que fornece uma via de mediação entre ambos por meio de uma interface semelhante a uma coleção para acessar objetos de domínio.
Estruturas PHP modernas, como Laravel e Symfony, interagem com bancos de dados via Mapeadores objeto-relacionais (ORMs); a Symfony usa o Doctrine como seu ORM padrão e a Laravel usa o Eloquent.
Ambos adotam abordagens diferentes em como a interação com o banco de dados funciona. Com o Eloquent, os modelos são gerados para cada tabela de banco de dados, formando a base de interação. O Doctrine, no entanto, usa o padrão de Repositório onde cada Entidade tem um repositório correspondente contendo funções auxiliares para interagir com o banco de dados. Embora o Laravel não forneça essa funcionalidade de forma imediata, é possível usar o padrão de Repositório em projetos Laravel.
Um dos principais benefícios do padrão de Repositório é que ele nos permite usar o Princípio de inversão de dependência (ou o código para abstrações, não concretizações). Isso torna nosso código mais resistente às alterações, como se uma decisão fosse tomada mais tarde para mudar para uma fonte de dados que não é suportada pelo Eloquent.
Ele também ajuda a manter o código organizado e a evitar duplicação, pois a lógica relacionada ao banco de dados é mantida em um só lugar. Embora este benefício não seja imediatamente aparente em projetos pequenos, fica mais visível em projetos de grande escala que precisam ser mantidos durante muitos anos.
Neste artigo, mostrarei a você como implementar o padrão de Repositório em seus aplicativos Laravel. Para isso, criaremos uma API para gerenciar pedidos recebidos de clientes de uma empresa.
Pré-requisitos
- Uma compreensão básica do PHP e Laravel
- PHP 7.4
- Composer instalado globalmente
- cURL
- Git
- jq (opcional)
- O instalador do Laravel
- Acesso a um banco de dados MySQL
Primeiros passos
Crie um novo projeto Laravel e use cd no diretório usando os comandos a seguir.
Configure o banco de dados
Para este tutorial, usaremos o MySQL como o nosso banco de dados. Para fazer isso, no arquivo .env, atualize os parâmetros relacionados ao banco de dados conforme mostrado abaixo.
Por fim, usando seu aplicativo de gerenciamento de banco de dados preferido, crie um novo banco de dados chamado order_api
.
Gere os dados iniciais para o banco de dados
Estamos criando um aplicativo de gerenciamento de pedidos, então vamos criar o modelo para ele executando o seguinte comando.
O argumento -a
permite que o Artisan saiba que queremos criar um arquivo de migração, umpropagador, uma fábrica e um controlador para o modelo Order.
O comando acima criará cinco novos arquivos:
- Um controlador em app/Http/Controllers/OrderController.php
- Uma fábrica de banco de dados em database/factories/orderFactory.php
- Um arquivo de migração em database/migrations/YYYY_MM_DD_HHMMSS_create_orders_table.php
- Um modelo localizado em app/Models/Order.php
- Um arquivo propagador em database/seeders/OrderSeeder.php e
Em database/migrations/YYYY_MM_DD_HHMMSS_create_orders_table.php, atualize a função up
para corresponder ao seguinte.
Conforme especificado no arquivo de migração, a tabela order
terá as seguintes colunas:
- Um ID. Esta será a chave primária da tabela.
- Os detalhes do pedido.
- O nome do cliente que fez o pedido.
- Se a pedido foi atendido ou não.
- Quando o pedido foi criado e atualizado,
created_at
eupdated_at
, fornecidos pela função detimestamps
.
Em seguida, vamos atualizar a OrderFactory
para que ele possa usá-la para gerar uma ordem fictícia para propagar o banco de dados. Em database/factories/OrderFactory.php, atualize a função definition
para que corresponda ao seguinte.
Em seguida, abra odatabase/seeders/OrderSeeder.php e atualize a função run
para corresponder ao seguinte.
Isso usa OrderFactory
para criar 50 pedidos no banco de dados.
Em src/database/seeders/DatabaseSeeder.php, adicione o seguinte à função run
.
Isso executa o comando QuoteSeeder
quando o comando db:seed
do Artisan é executado.
Por fim, execute suas migrações e propague o banco de dados usando o seguinte comando.
Se você abrir a tabela de pedidos, verá os pedidos recém-propagados.
Crie o repositório
Antes de criar um repositório para o modelo Order
, vamos definir uma interface para especificar todos os métodos que o repositório deve declarar. Em vez de depender diretamente da classe do repositório, nosso controlador (e qualquer componente de pedido que possamos construir no futuro) dependerá da interface.
Isso torna nosso código flexível porque, caso seja necessário fazer uma mudança no futuro, o controlador não é afetado. Por exemplo, se decidimos terceirizar o gerenciamento de pedidos para um aplicativo de terceiras partes, podemos construir um novo módulo que esteja em conformidade com a assinatura da OrderRepositoryInterface
e trocar as declarações vinculativas, e nosso controlador funcionará exatamente como esperado, sem tocar em uma única linha de código no controlador.
No diretório app, crie uma nova pasta chamada Interfaces. Em seguida, nas interfaces, crie um novo arquivo chamado OrderRepositoryInterface.php e adicione o seguinte código a ele.
Em seguida, na pasta app, crie uma nova pasta chamada Repositórios. Nesta pasta, crie um novo arquivo chamado OrderRepository.php e adicione o seguinte código a ele.
Além da flexibilidade fornecida pela interface, encapsular consultas dessa maneira tem a vantagem adicional de que não é necessário duplicar consultas em todo o aplicativo.
Se, no futuro, decidirmos recuperar apenas pedidos não cumpridos na função getAllOrders()
, só teríamos de fazer uma alteração em um lugar, em vez de rastrear todos os lugares onde Order::all()
é declarado, arriscando deixar alguns passar.
Criando os controladores
Com nosso repositório em vigor, vamos adicionar uns códigos ao nosso controlador. Abra app/Http/Controllers/OrderController.php e atualize o código para corresponder ao seguinte.
O código injeta uma instância OrderRepositoryInterface
por meio do construtor e usa os métodos relevantes do objeto em cada método de controlador.
Primeiro, dentro do método index()
, ele chama o método getAllOrders()
definido no orderRepository
para recuperar a lista de pedidos e retorna uma resposta no formato JSON.
Em seguida, o método store()
chama o método createOrder()
no orderRepository
para criar um novo pedido. Isso obtém os detalhes da ordem que precisa ser criada como uma matriz e retorna uma resposta bem-sucedida posteriormente.
Dentro do método show()
no controlador, ele recupera o Id
exclusivo do pedido na rota e a passa para o getOrderById()
como um parâmetro. Isso busca os detalhes do pedido com um ID correspondente do banco de dados e retorna uma resposta no formato JSON.
Em seguida, para atualizar os detalhes de um pedido já criado, ele chama o método updateOrder()
no repositório. Isso requer dois parâmetros: o ID exclusivo do pedido e os detalhes que precisam ser atualizados.
Por fim, o método destroy()
recupera o ID exclusivo de um pedido específico na rota e chama o método deleteOrder()
no repositório para excluí-lo.
Adicionando as rotas
Para mapear cada método definido no controlador para rotas específicas, adicione o seguinte código a routes/api.php.
Vincule a interface e a implementação
A última coisa que precisamos fazer é ligar OrderRepository
a OrderRepositoryInterface
no Contêiner de serviço da Laravel; isso é feito através de um Prestador de serviço. Crie um com o seguinte comando.
Abra o app/Providers/RepositoryServiceProvider.php e atualize a função register
para corresponder ao seguinte.
Por fim, adicione o novo prestador de serviços à matriz providers
em config/app.php.
Teste o aplicativo
Execute o aplicativo novamente usando o seguinte comando.
Por padrão, o aplicativo fornecido estará disponível em http://127.0.0.1:8000/. Usando Postman ou cURL, podemos fazer solicitações para a nossa API recém-criada.
Execute o seguinte comando para testar o endpoint /api/orders
usando cURL:
Você verá uma saída JSON parecida com o exemplo abaixo em seu terminal, que foi truncado para ajudar na legibilidade.
É assim que se usa o padrão de Repositório em um aplicativo Laravel
Neste artigo, aprendemos sobre o padrão de Repositório e como usá-lo em um aplicativo Laravel. Também vimos alguns dos benefícios que ele oferece a um projeto em grande escala, sendo um deles um código de acoplamento flexível, onde codificamos para abstrações, e não implementações concretas.
No entanto, terminarei com um lembrete de precaução. Para pequenos projetos, essa abordagem vai parecer muito trabalho e um código de modelo para devoluções que podem não ser imediatamente aparentes. Portanto, é importante que você considere o tamanho do projeto apropriadamente antes de adotar essa abordagem.
A base de código completa deste tutorial está disponível no GitHub. Sinta-se à vontade para explorar mais. Boa codificação!
Oluyemi é um entusiasta de tecnologia com um histórico na Engenharia de Telecomunicações. Com interesse em resolver os problemas do dia a dia encontrados pelos usuários, ele se aventurou na programação e, desde então, dirigiu suas habilidades de solução de problemas para a criação de software para a Web e para dispositivos móveis.
Um engenheiro de software de pilha completa com paixão por compartilhar conhecimento, Oluyemi publicou um bom número de artigos técnicos e conteúdo em vários blogs na Internet. Por ser experiente em tecnologia, seus hobbies incluem experimentar novas linguagens e estruturas de programação.
Publicações relacionadas
Recursos relacionados
Twilio Docs
De APIs a SDKs e aplicativos de amostra
Documentação de referência de API, SDKs, bibliotecas auxiliares, guias de início rápido e tutoriais para sua linguagem e plataforma.
Centro de Recursos
Os mais recentes e-books, relatórios do setor e webinars
Aprenda com especialistas em engajamento do cliente para melhorar sua própria comunicação.
Ahoy
Centro da comunidade de desenvolvedores da Twilio
Melhores práticas, exemplos de código e inspiração para criar comunicações e experiências de engajamento digital.