Arquitetura NodeJs
Estava fazendo uma api em node + typescript , express , prisma e jest para testes para faculdade , e me surgiu uma duvida sobre arquitetura em pastas , em java por exemplo era bem definidinho dto,repositories etc em node eu nunca vi um padrão que o povo utiliza , (tenho a impressão que cada um tem a sua ), vocês conhecem algum padrão ou usam algum?
em node com express que não é opinado você pode usar a organização de pastas que quiser!
Frameworks opinados são menos usados no node!
Você pode usar a mesma organização que usava com java! Ou criar uma propria!
Pessoalmente uso uma que chamo de mini-mvc Que é um mvc por áreas!
Também gosto de fatia vertical https://dev.to/devdoido/conheca-o-clean-vertical-sliced-architecture-a-uniao-dos-2-mundos-4gnd
pra api, algo que pode ser usado é a algo semelhante a estrutura do tabnews, basta olhar o Repositório oficial
Eu uso a arquitetura sugerida pelo NestJs. Acredito que seja a melhor para dar manutenção, principalmente em projetos grandes.
segue um exemplo: https://github.com/dev-Raffa/CMS---blog
Olha a branch making
Eu diria que mesmo em Java não é bem assim, você até tem o Spring, mas até onde eu entendo (que não é muito), o básico do básico, se divide em controller, service e repository, mas esses são só os esteriótipos do container de injeção de dependência dele, você pode fazer tudo funcionar só com controller e repository por exemplo. Se você for das antigas, o Java tinhas os Servelets e provavelmente você criaria um DAO também.
O ponto é que arquitetura não é algo relacionado a linguagem ou ecossistema, é algo que você aplica pois faz sentido organizar daquela forma, se você entende o que cada conceito significa, vai ser algo mais natural saber organizar o seu código sem se orientar pela maioria.
Se você aprendeu a separar em DTO, Repositories, e etc, organize assim também na suas aplicações Node que não vai ser lá um grande problema.
Como você pediu algumas sugestões, o meu apelo é que ao invés de se orientar pelos frameworks, ou confiar no jeito freestyle de alguém, você tente aprender sobre as arquiteturas de fato que já existem, e depois disso tirar suas próprias conclusões sobre como implementar no seu dia-a-dia. Uma série sensacional que aborda esse assunto é a do Herberto Graca: https://herbertograca.com/2017/07/03/the-software-architecture-chronicles/
Feito o aviso, minha recomendação é a arquitetura hexagonal, ela pode ser tão simples quanto implementar um spagetti code, e escalar tão complexa quanto uma implementação de DDD + Clean Architecture com Microsserviços. E como ela é bem simples, você pode usar qualquer padrão que você já conheça de outra arquitetura para organizar o seu código que provavelmente você consegue misturar bem as coisas
A ideia é bem simples, você pensa na sua aplicação, o que ela usa de fora (por exemplo o banco de dados), quem de fora usa ela (por exemplo o usuário num navegador web), e define interfaces para serem portas para cada um desses da aplicação, ai você implementa um adapter para essa porta, e depois instancia os objetos e passa cada adapter como dependência da sua aplicação (e ela como dependência dos adapters que usam ela), e pronto já tá implementado.
Um exemplo simples é uma aplicação web mesmo igual você sugeriu, você pode estruturar assim por exemplo:
- app/
- ports/
- in/
- FindPost.ts
- ListPosts.ts
- CreatePost.ts
- UpdatePost.ts
- DeletePost.ts
- out/
- PostRepository.ts
- in/
- services/
- PostService.ts
- ports/
- adapters/
- in/
- PostController.ts
- PostServiceTest.ts
- out/
- PrismaPostRepository.ts
- in/
Ai PostService
é uma classe que implementa as portas in, usa as portas out, e deve ser utilizada pelos adapters in como o PostController
ou um teste automatizado PostServiceTest
. As portas out são implementadas pelo PrismaPostRepository
lá nos adapters de out.
Links que eu recomendo sobre o assunto: https://jmgarridopaz.github.io/content/articles.html https://youtu.be/fkr6CNoMwx4
Minhas preferências (e a ordem que eu as escrevo):
/entities: entidades e regras de negócio do domínio - core da aplicação /use-cases: os casos de uso em si, onde há interação entre as entidades do domínio /repositories: persistência de dados (daí posso usar combinado com um ORM, ou não) /controllers: rotas da aplicação (antigamente eu usava um /routes também, mas passei a simplificar e usar somente o /controllers)
De fato o express permite essa liberdade pois ele não é um framework opinado, como por exemplo é o Spring Boot para o Java, ou até mesmo o NestJs para Javascript/Typescript. Mas eu prefiro o express ou fastify justamente por essa liberdade.
Se a codebase estiver bem documentada, você consegue separar a liberdade de libertinagem e evitar que sua aplicação vire uma "maçaroca".
Geralmente gosto de separar principalmente em models, services e controllers. Já usou o Nestjs? Ele tem um padrão de arquitetura bem legal