Diagrama com a estrutura dos modelos news, videos e galeria da MasterChef API, apresentando os campos e tipos de dados armazenados no MongoDB.

MasterChef API — Injeção de Dependência em uma API Node.js Arquitetura de Software

A MasterChef API é uma aplicação backend criada para tester a utilização de injeção de dependência com tsyringe para desacoplar controllers, services, repositories, modelos do Mongoose e infraestrutura de banco de dados.

Feito com

  • Node.JS
  • Express
  • MongoDB
  • Mongoose
  • tsyringe
  • Docker

Contexto

Aplicações backend podem se tornar difíceis de manter quando controllers criam diretamente seus services, quando services conhecem implementações concretas de persistência ou quando a configuração do banco de dados fica espalhada pelo código. A MasterChef API foi desenvolvida como um estudo sobre como reduzir esse acoplamento em uma API de conteúdo. O domínio escolhido reúne notícias, vídeos e galerias armazenados no MongoDB e disponibilizados por endpoints REST construídos com Express e TypeScript.

Objetivo

O objetivo principal foi compreender e aplicar injeção de dependência em uma aplicação Node.js, separando o recebimento das requisições HTTP, a lógica da aplicação e o acesso ao banco de dados. O projeto também buscou exercitar o uso de interfaces, repositórios genéricos, decorators e tokens de resolução, além de criar um ambiente local reproduzível com Docker Compose.

Processo

A implementação começou pela modelagem dos conteúdos e pela criação dos schemas do Mongoose para as coleções news, videos e galeria. Em seguida, o acesso aos dados foi centralizado em um repositório abstrato genérico, responsável pelas consultas por identificador e pelas listagens paginadas.

Cada domínio recebeu um repository especializado, um service definido por contrato e um controller responsável por interpretar os parâmetros da requisição e produzir as respostas HTTP.

Por fim, todas as implementações foram registradas no container do tsyringe, e o processo de inicialização passou a resolver as dependências antes de conectar ao MongoDB e iniciar o servidor.

Decisões técnicas

A arquitetura foi dividida entre rotas, controllers, services, repositories, contracts, models, infraestrutura e configuração compartilhada. O container central registra dependências por meio de tokens baseados em Symbol, evitando a dependência direta de nomes textuais. Controllers recebem services, services recebem repositories e repositories recebem modelos do Mongoose.

O repositório abstrato concentra as operações comuns de consulta e paginação, reduzindo duplicações entre os três domínios. A aplicação utiliza TypeScript em modo estrito, decorators com emissão de metadados e módulos ES. O ambiente de desenvolvimento é composto por containers separados para a API e o MongoDB, com volume persistente, rede própria e health check antes da inicialização do backend.

Desafios

O principal desafio foi configurar corretamente a resolução de dependências em tempo de execução, pois interfaces do TypeScript não existem após a compilação. Para solucionar isso, foram definidos tokens explícitos para controllers, services, repositories, modelos e conexão com o banco.

Outro ponto importante foi preservar a tipagem genérica entre os contratos, documentos do Mongoose e repositórios. A inicialização também precisou respeitar a ordem entre a configuração do container, a conexão com o MongoDB e a abertura do servidor HTTP.

Resultados e aprendizados

O projeto resultou em uma API capaz de consultar conteúdos individuais e listagens paginadas de notícias, vídeos e galerias. A implementação demonstrou, na prática, que a injeção de dependência transfere a responsabilidade de criação dos objetos para um container central, permitindo que cada camada se concentre em sua própria função.

O estudo também reforçou a importância de programar orientado a contratos, manter o acesso aos dados isolado e organizar o bootstrap da aplicação. Como evolução, o projeto pode incorporar testes unitários com dependências simuladas, validação centralizada de parâmetros, tratamento global de erros, documentação OpenAPI e pipelines de integração contínua.