Repository Pattern, Contracts e Service layer no Laravel 6

Felippe Simoes
levantelab
Published in
4 min readJul 9, 2020

Antes de tudo, você precisa saber que a intenção dessa publicação é expressar meu ponto de vista sobre Repository Pattern e tentar explicar de forma mais acessível visto que a maioria dos conteúdos sobre esse assunto estão em inglês.

Então vamos lá, vamos começar a falar em partes:

  • O que é repositório?
  • Porque utilizar e principais benefícios do uso do Repository Pattern
  • Como implementar um padrão de repositório no Laravel 6

O que é repositório

Podemos definir o repositório sendo uma interface de acesso e manipulação de dados armazenados em um banco de dados criando uma ponte entre Modelos e Controladores.

Principais benefícios do uso de Repository Pattern

A ideia principal de usar o Repository Pattern é dissociar dependências regidas de modelos e controladores. Entendo que o modelo não deve ser responsável por se comunicar ou extrair dados do banco de dados e sim ser um objeto que represente uma determinada tabela/documento.

Alguns benefícios importantes que Repository Pattern nos oferece:

  • Centralização da lógica de acesso aos dados e facilidade na manutenção do mesmo;
  • Lógica de regra de negócios e dados podendo ser testadas separadamente;
  • Melhor organização da aplicação;
  • Redução da duplicidade de código;
  • Redução de chance de cometer erros de programação;

Como implementar

Para exemplificar vamos ter duas entidades: Produtos e Categorias. E neles implementar o Repository Pattern, Service Layer e Resources.

1- Vamos criar nossos controladores de Produtos e Categoria

2- Criar nossos modelos

3- Vamos criar nossa estrutura de Repositories, Contracts e Services

Para Repositories > Criamos em App\Repositories;

Para Contracts > Criamos em App\Repositories\Contracts;

Para Services > Criamos em App\Services;

Então temos a estrutura abaixo:

Antes de criarmos nossos Repositories, vamos definir nossas interfaces para que possamos trabalhar com a lógica orientada a interfaces que vai nos garantir um padrão de quem for utilizar o repositório, nela vamos definir as assinaturas dos nossos métodos.

Feito isso teremos as seguintes Interfaces:

Para que possamos injetar nossas Interfaces sem causar um erro temos que fazer um bind da Interface, visto que o Service Injection do Laravel tenta criar um Objeto da Classe que está sendo injetada.

Então vamos resolver isso da seguinte forma:

3.1- Vamos criar um Provider para realizer nossos binds

3.2- Vamos fazer o bind das interfaces

3.3- Vamos registrar nosso RepositoryServiceProvider

Dentro do diretório > config\app.php

No array de providers insira :

3.4- Vamos definir nossos Repositories:

Importante assinarmos o métodos igual foi declaro nas Interfaces.

Então vamos lá:

  • CategoryRepository

Na nosso Construtor injetamos o Modelo de Category e definimos nossos métodos. Além de implementarmos o nosso Contrato de CategoryRepositoryInterface

O mesmo vamos fazer no nosso ProductRepository

  • ProductRepository

Agora temos já implementados nossos Repositories, vamos pensar agora nos Services, nele é onde definimos o modelo de negócios.

Vamos definir nossos Services dentro do diretório App>Services como na imagem abaixo:

  • ServiceCategory.php

No nosso Construtor injetamos a Interface de CategoryRepositoryInterface. Lembra que fizemos o bind ? Então o service Injection do Laravel está retornando um objeto do CategoryRepository.

A mesma coisa no ProductService.php

  • ProductService

Estamos quase no fim, por ultimo vamos implementar nossos Controladores com seus devidos métodos e também com seus requests e resources :)

CategoryController

Repara que no nosso construtor injetamos nosso ServiceCategory, ele vai fazer toda a regra de negocio e o controlador fica enxuto e somente delegando como foi proposto!

Nos métodos que há necessidade de validações usamos os Requests do Laravel que vai definir quais informações são obrigatórias por exemplo. Para criar um Request usamos o seguinte comando:

E também vamos criar nosso Resource que vai nos ajudar nos retornos das respostas. Com ele podemos, basicamente falando, escolher o que vai ser retornado para o usuário e até mesmo mudar o nome dos atributos de resposta. Vamos lá!!

Repara que nesse exemplo básico, na linha 18 mudamos o 'uiid' da categoria para 'indetify' e no Controlador de Category usamos o resource para retornar informações conforme o exemplo da linha 23.

O mesmo foi feito na controlador de Produtos pessoal. Não vou aprofundar muito no assunto de Requests e Resources porque o intuito desse post é Repository Pattern.

Com isso, chegamos ao fim, pessoal. Tomara que tenha ficado claro de como implementar o Repository Pattern e seus benefícios, portanto, sempre que precisarmos de alguma leitura ou persistência de dados utilizamos nossa interface.

Disponibilizo o projeto de exemplo no meu github.

Até mais!

--

--