Controller acessando Repository é uma boa prática?

Bom dia, pessoal. Será que é uma boa prática o controller acessar os repository, diretamente. Dessa forma poupa alguns códigos que seriam apenas de repasse do service para repository.

Por outra parte, não sei se fica tão robusto. A principio os services definiriam claramente a fronteira de nossa aplicação (regras de negócio) com apresentação.

Qual é a experiência de vcs neste ponto?

Eu particularmente sempre centralizei em classes de serviço, deixando somente no controller o que diz respeito à camada de apresentação, tudo o que diz respeito à domínio internalizado nos services, mesmo que em um primeiro momento não houvessem regras a serem aplicadas.

1 curtida

Pois é, às vezes parece perda de tempo, pq muitos services apenas estariam delegando para os repository.

Por outra parte a evolução é mais tranquila, se tiver qualquer regra é só colocar no service.

Também me deu a impressão de ficar mais robusto, com uma fronteira bem definida. Tudo que passa pelo services tem validação, todos os parâmetros são validados.

Qual forma será mais utilizada no mercado?

Olha, se teu service tá apenas delegando para o repository sem qualquer regra de negócio aplicada, eu acho perda de tempo mesmo.

Você pode ter 100 endpoints no seu sistema, e em apenas um precisa de uma lógica extra? Adiciona o service só ali. Não vejo vantagem em adicionar essa camada ali só pra manter consistência.

Se precisar inserir regra depois, cria o service. Não precisa pagar o preço da burocracia antes.

2 curtidas

Pra consultas direto no banco também acho perda de tempo ficar criando um método no service só pra chamar um método do repositório. É um capricho que deixa o desenvolvimento burocrático. Se um dia mudar, refatora, mas isso não é rotineiro.

1 curtida

No caso de uma consulta que tenha um filtro obrigatório, seria melhor deixar num service para poder levantar uma exceção de negócio?

Nesse caso você vai ter um service (ou qualquer outro mecanismo como Bean Validation) que vai validar os dados do filtro. O método do repositório que vai retornar o resultado só deve ser chamado caso passar nessa validação.

1 curtida

Manter as fronteiras definidas entre controller, service e repository é sempre a melhor solução. Hoje as regras de negócio podem ser simples, mas conforme a aplicação evolui, vão ficando mais complexas. Imagina ter que alterar 20 controllers pra incluir uma modificação qualquer de um Dao, quando bastaria mexer em 1 classe de serviço?! Escreva o código pensando no futuro tbm (manutenção, performance, legibilidade).

4 curtidas

Não precisa amarrar o retorno de uma consulta com regras em um service. Isso que faz complicar e gerar burocracia quando nao é o caso de ter validação. Caso a requisição x exija validação, chama o service pra validar (ou bean validation no caso do Java), caso ok chama o repositório pra retornar os dados. A exemplo do caso citado pelo colega, que precisa validar os dados do filtro antes de retornar a consulta.

Controller não é pra ser algo totalmente burro, não deve ter regras de negócio mas pode decidir se vai validar ou nao o que ta entrando. Não é a toa o nome Controller. E isso não tem nada haver com performance.

Importante é ter agilidade no desenvolvimento, não cometer amarrações e a empresa ter retorno imediato do previsto de valor pro Negócio, sem perder tempo com burocracias e exoterismos.

Outra burocracia muito comum entre os puristas é criar interface sem necessidade, onde sempre só tem uma implementação daquele contrato.

Meu único receio é “regrinhas” começar a ficar espalhadas pelos controllers.

Acho que se a consulta tem alguma validação tanto na entrada(filtro obrigatório) ou na saída(levantar exceção caso a consulta retorne vazio) o melhor seria deixar num service, né?

Quando a consulta não tem validações, nem na entrada nem na saída, não vejo necessidade de colocar num service.

Validações de dados de entrada eu sempre aplico no controller, nos services somente o que diz respeito à regras de negócio e afins, gosto deste formato pois fica bem simples e dividido o código.
Logicamente isso não é regra, se colocar tudo junto e misturado vai funcionar do mesmo jeito, porém a medida em que se evoluí a aplicação, vai aumentando a complexidade de manutenibilidade ou novas implementações acabam sendo bem maiores e demoradas.

Eu aprendi que essas validações “deviam” ser colocadas nos services. Dessa forma eu posso usar o mesmo service em várias partes do sistema sem precisar duplicar as validações.

No meu caso eu sempre utilizo Beans Validation, então estas validações eu não preciso reimplementar nada para verificar se um dado é nulo, vazio, maior ou menor que zero e coisas do tipo, garanto que os dados só cheguem aos services se já estiverem todos Ok na entrada.
São abordagens diferentes, não existe certo e errado ao meu ver neste contexto se ambas atendem o propósito da solução.

1 curtida

A regra deve ficar no service ou bean validation. Mas você pode decidir chamar ou não a validação na controller, dependendo de cada caso requisitado. Requisição pra uma combo simples por exemplo não precisaria de validação. Já esse caso citado do filtro sim.

A exemplo do próprio bean validation, a validação pode ser chamada na controller através de anotação nos parâmetros da requisição, fazendo o backend retornar bad request (400).

1 curtida

Mudança é uma constante em desenvolvimento. Logo imagine um sistema que em alguns casos o Controller chama o Service e em outros chama o Repository. Isso é uma caracteristica de um sistema padronizado?

Vamos pensar um pouco: Digamos que em uma determinada funcionalidade não tenha nenhuma regra de negocio, então decidi que o Controller nesse caso vai chamar direto o Repository, em um certo dia alguém resolve colocar uma regra de negocio, dai eu tenho que criar um Service e colocar a regra de negocio, mas não é só isso, tenho que varrer todos os meus Controllers pra verificar quem esta chamando o Repository em questão pra trocar pelo Service, eis duas perguntas: 1 - Quanto tempo de manutenção isso vai gastar? 2 - Se eu esquecer algum Controller o que vai acontecer?

Volto a pergunta do topico: Controller acessar o repository é uma boa pratica? Se for qual o embasamento no arcabouço da literatura técnica isso se sustenta? Vamos pensar um pouco?

Parece que há um “tradeoff” aqui. Robustez, Burocracia e mais linhas de código vs Menos Robustez, flexibilidade e código mais enxuto.

O que tenho observado é que alguns anos atrás era quase um padrão o controller chamar apenas services.

Recentemente tenho visto vários projetos e profissionais bem conceituados usando a outra abordagem. Controller chamando services e repository, conforme a demanda.

Não tem varredura se atender demandas de forma incremental. Ai voce já tem um problema de gestão.

Ja trabalhei com ambas as abordagens, e era muito mais entediante trabalhar de forma burocratica.

Será que a abordagem do controller chamando apenas services é mais robusta? O que vc conseguiu perceber empiricamente falando.

Certamente essa abordagem é mais entediante, demorada e tem mais linhas de código, porém fico com receio de que essa abordagem é mais robusta.

Na abordagem de controller chamando repository, nada impede de um controler chamar um save diretamente, sem passar pelas regras de negócio. Isso é muito ruim. Para evitar isso teria que criar interfaces e assim aumentar as linhas de código e burocracia.

No livro Arquitetura Limpa de Robert C. Martin diz que: “A camada de interface não pode conhecer nada da camada de acesso a dados.”, no nosso caso o Controller seria a entrada da nossa API, portanto chamar diretamente o Repository quebra o paradigma.

Isso varia de equipe para equipe, de gestão pra gestão. Voce tem que seguir o que for mais prático pro seu dia a dia, independente do que Papas da TI preguem. Se tu ver o que javeiros pregavam no passado como correto iria cair da cadeira.

No final o que importa é o retorno financeiro pro Negócio, sem burocracias técnicas atrapalhando. Maioria dos programadores tem a visão muito fechada só pra código.

Por isso o nome Controller, é o controlador. Se nao o nome seria Mule. Voce impede ou nao de acordo com a requisição/demanda.