Skip to content

Santosdevbjj/NTT-Data-desafio-microservicos-em-Java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NTT-Java

Sistema de Microserviços em Java — NTT DATA

Bootcamp NTT DATA · Java e IA para Iniciantes


1. Problema de Negócio

Sistemas monolíticos de e-commerce enfrentam um gargalo crítico: qualquer alteração no catálogo de produtos exige o redeployment de toda a aplicação — incluindo o módulo de pedidos, mesmo que este não tenha sido modificado. Em cenários de alta frequência de mudança (precificação dinâmica, gestão de estoque, promoções relâmpago), isso gera indisponibilidade programada, acoplamento entre equipes e risco operacional elevado.

O desafio proposto pelo bootcamp simula exatamente esse contexto: construir dois domínios de negócio — catálogo de produtos e simulação de pedidos — como serviços independentes, capazes de evoluir, escalar e falhar de forma isolada, sem impacto mútuo.


2. Contexto

O projeto foi desenvolvido dentro do Bootcamp NTT DATA — Java e IA para Iniciantes como desafio prático de arquitetura distribuída com Spring Cloud. O escopo contempla:

  • Um serviço de catálogo com operações completas de CRUD sobre produtos
  • Um serviço de pedidos que consome o catálogo em tempo real para simular ordens de compra
  • Uma camada de roteamento e segurança centralizada via API Gateway
  • Um servidor de descoberta de serviços que permite comunicação dinâmica entre os módulos sem URLs hardcoded

A arquitetura reflete padrões utilizados em sistemas de e-commerce e ERPs corporativos, onde o desacoplamento entre domínios é requisito não negociável para times que entregam em paralelo.


3. Premissas

  • O ambiente de execução é local (desenvolvimento), sem orquestração de containers; Docker Compose e Kubernetes estão fora do escopo deste desafio
  • A persistência do catálogo utiliza banco H2 em memória, suficiente para validar o comportamento transacional sem dependência de infraestrutura externa
  • A autenticação via Basic Auth no API Gateway representa o controle de acesso mínimo viável para o escopo do bootcamp; em produção seria substituída por OAuth2/JWT
  • O RestTemplate com @LoadBalanced foi mantido por compatibilidade com o stack Spring Boot 2.7.x do bootcamp; projetos greenfield utilizariam WebClient reativo
  • A simulação de pedidos não persiste ordens no banco — o foco é validar a comunicação inter-serviços e o cálculo de totais em tempo real

4. Estratégia da Solução

A solução foi decomposta em quatro módulos independentes com responsabilidades bem definidas:

desafio-nttdata/
├── discovery-server    → Eureka Server           (porta 8761)
├── produto-service     → CRUD de catálogo        (porta 8101, H2)
├── pedido-service      → Simulação de pedidos    (porta 8201)
└── api-gateway         → Roteamento + Basic Auth (porta 8701)

Fluxo de uma requisição de pedido:

Cliente HTTP
    ↓
API Gateway :8701  —  autentica via Basic Auth
    ↓
pedido-service :8201  —  recebe lista de IDs de produtos
    ↓
produto-service :8101  —  consultado via Eureka + RestTemplate @LoadBalanced
    ↓
PedidoResponse  —  lista de produtos + total calculado retorna ao cliente

Stack técnica:

Camada Tecnologia Versão
Framework base Spring Boot 2.7.x
Service Discovery Spring Cloud Netflix Eureka 2021.0.x
API Gateway Spring Cloud Gateway 2021.0.x
Comunicação HTTP RestTemplate + @LoadBalanced
Persistência Spring Data JPA + H2
Segurança Spring Security Basic Auth
Runtime Java 17

5. Decisões Técnicas e Trade-offs

Por que Eureka e não um service mesh (Istio / Linkerd)? Para o escopo do bootcamp, o Eureka oferece visibilidade explícita do registro de serviços via dashboard (localhost:8761) com zero configuração de infraestrutura externa. Um service mesh teria overhead operacional — configuração de sidecar proxies, mTLS, observabilidade distribuída — incompatível com o objetivo pedagógico do desafio. A troca direta é: operabilidade imediata vs. controle granular de tráfego em produção.

Por que H2 em memória e não PostgreSQL? A escolha elimina a dependência de um banco externo para rodar o projeto, reduzindo a fricção de onboarding a zero. O ddl-auto: update garante que o schema seja criado automaticamente. A migração para PostgreSQL exigiria apenas alteração do datasource no application.yml e adição da dependência JDBC — o código de negócio permanece intacto graças à abstração do Spring Data JPA. Trade-off aceito: dados não sobrevivem a um restart do serviço.

Por que Basic Auth e não OAuth2/JWT? O Basic Auth no API Gateway centraliza a autenticação sem exigir um Authorization Server separado (Keycloak, Spring Authorization Server). Para um sistema de produção com múltiplos consumidores e tokens de refresh, esse seria o primeiro ponto a ser substituído. A decisão foi consciente e registrada como dívida técnica aceitável dentro do escopo do bootcamp.

Por que RestTemplate e não WebClient? O RestTemplate com @LoadBalanced integra nativamente com o Eureka Client, resolvendo endereços pelo nome lógico do serviço — http://produto-service/produtos/{id} — sem acoplamento a IPs ou portas. Em projetos com Spring Boot 3.x e programação reativa, WebClient seria a escolha natural; aqui, a legibilidade síncrona favorece o objetivo didático.

Por que implementar PedidoCliRunner além da API REST? O CLI Runner (CommandLineRunner) demonstra que a camada de serviço é agnóstica ao protocolo de entrega. A mesma lógica de negócio pode ser consumida via REST ou via terminal interativo, evidenciando na prática a separação entre Controller e Service — um dos princípios mais cobrados em entrevistas técnicas de Java backend.


6. Resultados

O sistema entregou, de forma funcional e desacoplada:

  • 4 serviços independentes rodando simultaneamente, registrados e descobertos via Eureka sem configuração manual de URLs
  • CRUD completo de produtos com persistência transacional via JPA/H2 e endpoints REST versionáveis
  • Simulação de pedidos com cálculo de total em tempo real, consumindo o catálogo via service discovery — eliminando acoplamento de endereço
  • API Gateway centralizando roteamento e autenticação, tornando os serviços internos invisíveis para o cliente externo
  • CLI interativo comprovando que a lógica de negócio é agnóstica ao protocolo de entrega
  • Arquitetura extensível: adicionar um novo domínio (ex: pagamento-service) requer apenas registrá-lo no Eureka e adicionar a rota no Gateway — os demais serviços permanecem intocados

7. Próximos Passos

  • Migrar para Spring Boot 3.x e substituir WebSecurityConfigurerAdapter (deprecated) por SecurityFilterChain
  • Substituir Basic Auth por OAuth2/JWT com Authorization Server (Keycloak ou Spring Authorization Server)
  • Substituir RestTemplate por WebClient com suporte reativo e timeouts configuráveis
  • Adicionar persistência real ao pedido-service (PostgreSQL) para manter histórico de ordens
  • Implementar Circuit Breaker com Resilience4j para tolerância a falhas quando o produto-service estiver indisponível
  • Containerizar com Docker Compose para eliminar a dependência de múltiplos terminais na execução
  • Adicionar testes de integração cobrindo o fluxo completo: Gateway → pedido-service → produto-service

⚙️ Como Executar

Pré-requisitos: Java 17+ · Maven 3.8+

# 1. Clone o repositório
git clone https://github.com/Santosdevbjj/NTT-Data-desafio-microservicos-em-Java.git
cd NTT-Data-desafio-microservicos-em-Java

# 2. Compile todos os módulos
mvn clean install

# 3. Inicie os serviços na ordem abaixo (terminais separados)
cd discovery-server && mvn spring-boot:run   # aguarde o Eureka subir em :8761
cd produto-service  && mvn spring-boot:run
cd pedido-service   && mvn spring-boot:run
cd api-gateway      && mvn spring-boot:run

Endpoints via API Gateway — Basic Auth: user / password

Operação Método URL
Criar produto POST http://localhost:8701/produtos
Listar produtos GET http://localhost:8701/produtos
Buscar produto GET http://localhost:8701/produtos/{id}
Atualizar produto PUT http://localhost:8701/produtos/{id}
Deletar produto DELETE http://localhost:8701/produtos/{id}
Simular pedido POST http://localhost:8701/pedidos/simular

Dashboard Eureka: http://localhost:8761

Payload de exemplo — simular pedido:

{
  "produtoIds": [1, 2, 3]
}

Resposta esperada:

{
  "produtos": [
    { "id": 1, "nome": "Produto A", "descricao": "...", "preco": 49.90 },
    { "id": 2, "nome": "Produto B", "descricao": "...", "preco": 29.90 },
    { "id": 3, "nome": "Produto C", "descricao": "...", "preco": 19.90 }
  ],
  "total": 99.70
}

Portfólio Sérgio Santos LinkedIn Sérgio Santos

About

Monolito acoplado trava deploys e equipes | 4 microsserviços Spring Boot com Eureka, API Gateway e CRUD desacoplado | Arquitetura distribuída pronta para escalar domínios independentemente

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages