Controller acessando Repository é uma boa prática?
24 respostas
javaprogramação
E
Eduardocar831
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.
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
Eduardocar831
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
AbelBueno2 likes
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.
J
javaflex1 like
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
Eduardocar831
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?
J
javaflex1 like
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.
M
marcoacsilva4 likes
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).
J
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
Eduardocar831
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.
J
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
Eduardocar831
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.
J
Jonathan_Medeiros1 like
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.
J
javaflex1 like
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).
A
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
Eduardocar831
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.
J
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
Eduardocar831
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.
A
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.
J
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.
J
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.
J
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.
J
javaflex
Importante não ter amarrações, isso que condena o futuro.
E
Eduardocar831
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.
J
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.