Controller acessando Repository é uma boa prática?

24 respostas
javaprogramação
E

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?

24 Respostas

Jonathan_Medeiros

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.

E

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?

A

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.

javaflex

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.

E

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?

javaflex

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.

marcoacsilva

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).

javaflex

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.

E

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.

Jonathan_Medeiros

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.

E

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.

Jonathan_Medeiros

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.

javaflex

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).

andrebmarinho

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?

E

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.

javaflex

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.

E

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.

andrebmarinho

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.

javaflex

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.

javaflex

Nao sigo o que vá me atrapalhar na entrega de resultados pra faturar. Imagina se eu seguisse o que literaturas pregavam de complexo no passado como na epoca do extremo DDD? Eu sempre ignorava e ganhava com isso.

Jonathan_Medeiros

Existe em tudo, você precisa sempre avaliar os ganhos e percas e se questionar qual o melhor caminho à seguir no momento.

Pensar somente no atual momento é condenar o futuro da solução, e pensar só no futuro é sacrificar o momento atual, por isso vale sempre avaliar, mas visando tanto o atual momento como o futuro também.

javaflex

Importante não ter amarrações, isso que condena o futuro.

E

Nisso concordo contigo. Sempre achei uma furada fazer um sistema usando DDD. Eu sigo a moda antiga, modelo o banco primeiro, seguindo o modelo relacional, e ainda por cima trabalho com entidades anêmicas. Toda a regra de negocio nos services. Consigo ser muito mais produtivo assim e as pessoas que entram no projeto conseguem dar manutenção tranquilamente. Testes apenas nos services e testes de integração.

Inclusive estou seguindo uma dica tua, rsrsrs. A menor quantidade possível de javascript no front. Já “cuspo” o html prontinho do server. Claro, não é uma SPA.

javaflex

É por ai mesmo, seguir só o que for mais prático pra fluir seu horizonte e conseguir o máximo de retorno financeiro, sem exageros nem de um lado, nem de outro, buscar o equilíbrio. É bom sempre avaliar o que for proveitoso das literaturas, não seguir como se fosse religião.

Também trabalho orientado a banco. Sem as amarrações do modelo orientado a objetos, uso DTOs conforme a demanda. Pelo menos pra mim também é muuuito mais produtivo e sem problemas de uma funcionalidade impactar a outra.

Essa questão de se complicar com SPA pra tudo sem ter necessidade também rola muito. Claro que é mais adequado em alguns cenários e traz retorno. Mas quando não é, principalmente em sistemas usados por funcionários internos, nao precisa se complicar só pela moda, criando um abismo entre projetos front e back só pra entregar o html ao browser, sem o usuário precisar de fluidez e n interações na tela que ele trabalha. Claro, sempre o mínino de javascript necessário.

Criado 27 de outubro de 2020
Ultima resposta 29 de out. de 2020
Respostas 24
Participantes 6