Skip to content

About

Monolithic Application using DDD and Clean Code

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

50 Commits

Folders and files

Repository files navigation

Algafood API

API REST para gerenciamento de restaurantes, cardápios, usuários, grupos, permissões e pedidos. O projeto foi construído com Spring Boot e organiza a aplicação em camadas bem definidas, com persistência em MySQL, migrações via Flyway, documentação OpenAPI, envio de e-mails transacionais e armazenamento de fotos de produtos em disco local ou Amazon S3.

Visão geral

O sistema cobre o ciclo principal de um marketplace de alimentação:

  • cadastro e manutenção de cozinhas, estados, cidades e formas de pagamento;
  • gestão de restaurantes, responsáveis, produtos e fotos de produtos;
  • cadastro de usuários, grupos e permissões;
  • criação de pedidos, consulta com filtros e evolução do fluxo de status;
  • emissão de estatísticas de vendas diárias;
  • envio de e-mails quando pedidos são confirmados ou cancelados.

Tecnologias e bibliotecas

Item Uso no projeto
Java 21 Linguagem principal
Spring Boot 3.5.3 Base da aplicação
Spring Web API REST
Spring Data JPA Persistência e consultas
MySQL Banco de dados principal
Flyway Versionamento do schema
Bean Validation Validação de entrada
ModelMapper Conversão entre entidades e modelos da API
Spring Mail + FreeMarker E-mails com template HTML
AWS SDK S3 Armazenamento remoto de fotos
springdoc OpenAPI Swagger UI e especificação da API
Rest Assured + JUnit 5 Testes de integração

Arquitetura

O projeto segue uma separação clara de responsabilidades:

  • api: controladores, modelos de entrada e saída, assemblers e tratamento global de exceções.
  • domain: entidades, regras de negócio, serviços, filtros, eventos, listeners e contratos de repositório.
  • infrastructure: implementações de repositórios e integrações externas, como S3, SMTP e consultas customizadas.
  • core: configurações transversais, como OpenAPI, serialização, CORS, validações, e-mail e storage.

Essa estrutura facilita manutenção, testes e evolução do domínio sem acoplar as regras de negócio diretamente à camada HTTP.

Principais conceitos do domínio

Restaurantes

Cada restaurante possui:

  • nome;
  • taxa de frete;
  • cozinha associada;
  • endereço;
  • formas de pagamento aceitas;
  • usuários responsáveis;
  • produtos;
  • status de ativação e abertura.

Além do CRUD, a API permite ativar, inativar, abrir, fechar e administrar vínculos com responsáveis e meios de pagamento.

Pedidos

O pedido agrega:

  • restaurante;
  • cliente;
  • forma de pagamento;
  • endereço de entrega;
  • itens;
  • subtotal, taxa de frete e valor total;
  • código UUID gerado automaticamente;
  • status do fluxo.

Fluxo suportado:

  • CRIADO -> CONFIRMADO
  • CONFIRMADO -> ENTREGUE
  • CRIADO -> CANCELADO

Ao confirmar ou cancelar um pedido, a aplicação publica eventos de domínio e dispara e-mails com template HTML.

Fotos de produtos

O upload de foto é feito por multipart/form-data, com validações explícitas:

  • formatos aceitos: image/jpeg e image/png;
  • tamanho máximo: 500KB.

O armazenamento pode ser local ou via Amazon S3, definido por configuração.

Estrutura do repositório

src/main/java/com/thomazllr/algafood
├── api
│   ├── assembler
│   ├── common
│   ├── controller
│   └── model
├── core
│   ├── email
│   ├── jackson
│   ├── modelmapper
│   ├── openapi
│   ├── storage
│   ├── validations
│   └── web
├── domain
│   ├── entity
│   ├── event
│   ├── exception
│   ├── filter
│   ├── listener
│   ├── repository
│   └── service
└── infrastructure
    ├── repository
    └── service

src/main/resources
├── application.yml
├── db/migration
├── db/testdata
├── messages.properties
└── templates

src/test
├── java
└── resources

Banco de dados e migrações

O schema é criado e evoluído com Flyway em src/main/resources/db/migration. As migrações presentes cobrem:

  • criação inicial das entidades principais;
  • cidades e estados;
  • grupos, permissões e usuários;
  • pedidos e itens de pedido;
  • flags de ativação e abertura de restaurante;
  • responsáveis de restaurante;
  • código público do pedido;
  • foto de produto;
  • controle de atualização em forma de pagamento.

No perfil padrão, o Flyway também executa src/main/resources/db/testdata/afterMigrate.sql, que popula o banco com dados de exemplo. Isso é útil para desenvolvimento e demonstração.

Configuração

Pré-requisitos

  • Java 21 instalado;
  • MySQL em execução;
  • acesso de leitura e escrita ao banco configurado;
  • opcionalmente, credenciais de SMTP, Amazon S3 e Loggly.

Configuração padrão observada no projeto

O arquivo src/main/resources/application.yml define:

  • banco principal em jdbc:mysql://localhost:3306/algafood;
  • usuário root;
  • senha password333;
  • timezone padrão da aplicação em UTC;
  • armazenamento de fotos com tipo s3;
  • envio de e-mails com implementação smtp.

Variáveis de ambiente usadas

Variável Finalidade
API_EMAIL_KEY Senha da conta SMTP
ID_CHAVE_ACESSO Access key do S3
CHAVE_ACESSO_SECRETA Secret key do S3
LOGGLY_TOKEN Token de envio de logs

Observações importantes para rodar localmente

  • O diretório configurado para storage local é /home/thomazllr/Desktop/catalago, então em Windows ou outro ambiente será necessário ajustar esse caminho se quiser usar storage local.
  • Como o application.yml padrão está apontando para smtp e s3, subir a aplicação sem credenciais válidas pode falhar ou deixar funcionalidades quebradas.
  • Para desenvolvimento local, faz sentido sobrescrever as configurações para usar FAKE ou SANDBOX no e-mail e LOCAL no storage.

Exemplo de configuração local sugerida

Crie um perfil local, por exemplo application-local.yml, com algo nesta linha:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/algafood?createDatabaseIfNotExist=true&serverTimezone=UTC
    username: root
    password: password333

algafood:
  email:
    impl: FAKE
  storage:
    tipo: LOCAL
    local:
      diretorio-fotos: C:/temp/algafood/catalogo

Depois rode a aplicação com o perfil:

./mvnw spring-boot:run -Dspring-boot.run.profiles=local

No Windows PowerShell:

.\mvnw.cmd spring-boot:run "-Dspring-boot.run.profiles=local"

Como executar

1. Subir o MySQL

Garanta que exista conectividade com:

  • banco algafood;
  • usuário root;
  • senha password333.

2. Iniciar a aplicação

./mvnw spring-boot:run

No Windows PowerShell:

.\mvnw.cmd spring-boot:run

3. Acessar a documentação da API

Com a aplicação no ar, os endpoints de documentação ficam normalmente em:

  • http://localhost:8080/swagger-ui/index.html
  • http://localhost:8080/v3/api-docs

Endpoints principais

Cadastros básicos

Recurso Base
Cozinhas /cozinhas
Cidades /cidades
Estados /estados
Formas de pagamento /formas-pagamento
Grupos /grupos
Usuários /usuarios

Esses recursos oferecem operações de listagem, busca por ID, criação, atualização e remoção.

Restaurantes

Operação Rota
Listar restaurantes GET /restaurantes
Buscar restaurante GET /restaurantes/{id}
Criar restaurante POST /restaurantes
Atualizar restaurante PUT /restaurantes/{id}
Remover restaurante DELETE /restaurantes/{id}
Ativar PUT /restaurantes/{id}/ativo
Inativar DELETE /restaurantes/{id}/ativo
Ativar em lote PUT /restaurantes/ativacoes
Inativar em lote DELETE /restaurantes/ativacoes
Abrir PUT /restaurantes/{id}/abertura
Fechar PUT /restaurantes/{id}/fechamento
Filtrar por frete grátis GET /restaurantes/com-frete-gratis?nome=...

Formas de pagamento do restaurante

Operação Rota
Listar formas aceitas GET /restaurantes/{id}/formas-pagamento
Associar forma de pagamento PUT /restaurantes/{id}/formas-pagamento/{formaPagamentoId}
Desassociar forma de pagamento DELETE /restaurantes/{id}/formas-pagamento/{formaPagamentoId}

Responsáveis do restaurante

Operação Rota
Listar responsáveis GET /restaurantes/{restauranteId}/responsaveis
Associar responsável PUT /restaurantes/{restauranteId}/responsaveis/{usuarioId}
Desassociar responsável DELETE /restaurantes/{restauranteId}/responsaveis/{usuarioId}

Produtos

Operação Rota
Listar produtos do restaurante GET /restaurantes/{id}/produtos
Listar incluindo inativos GET /restaurantes/{id}/produtos?incluirInativos=true
Buscar produto GET /restaurantes/{id}/produtos/{produtoId}
Criar produto POST /restaurantes/{id}/produtos
Atualizar produto PUT /restaurantes/{id}/produtos/{produtoId}

Foto de produto

Operação Rota
Enviar ou substituir foto PUT /restaurantes/{restauranteId}/produtos/{produtoId}/foto
Consultar metadados da foto GET /restaurantes/{restauranteId}/produtos/{produtoId}/foto com Accept: application/json
Baixar ou redirecionar para a imagem GET /restaurantes/{restauranteId}/produtos/{produtoId}/foto com Accept: image/jpeg
Remover foto DELETE /restaurantes/{restauranteId}/produtos/{produtoId}/foto

Quando o storage estiver em S3, a API pode responder com redirecionamento 302 Found para a URL pública do objeto.

Grupos e permissões

Operação Rota
Listar permissões do grupo GET /grupos/{grupoId}/permissoes
Associar permissão PUT /grupos/{grupoId}/permissoes/{permissaoId}
Desassociar permissão DELETE /grupos/{grupoId}/permissoes/{permissaoId}

Usuários e grupos

Operação Rota
Listar grupos do usuário GET /usuarios/{usuarioId}/grupos
Associar grupo PUT /usuarios/{usuarioId}/grupos/{grupoId}
Desassociar grupo DELETE /usuarios/{usuarioId}/grupos/{grupoId}
Atualizar senha PUT /usuarios/{id}/senha

Pedidos

Operação Rota
Listar pedidos com paginação GET /pedidos
Buscar pedido por código GET /pedidos/{codigoPedido}
Criar pedido POST /pedidos
Confirmar pedido PUT /pedidos/{codigoPedido}/confirmacao
Marcar como entregue PUT /pedidos/{codigoPedido}/entregar
Cancelar pedido PUT /pedidos/{codigoPedido}/cancelamento

Filtros disponíveis em GET /pedidos:

  • clienteId
  • restauranteId
  • dataCriacaoInicio
  • dataCriacaoFim

Estatísticas

Operação Rota
Vendas diárias GET /estatisticas/vendas-diarias

Filtros disponíveis:

  • restauranteId
  • dataCriacaoInicio
  • dataCriacaoFim
  • timeOffset

O parâmetro timeOffset é normalizado pelo controlador e aceita formatos como -03:00 e -0300.

Paginação, serialização e cache

  • GET /cozinhas retorna paginação.
  • GET /pedidos retorna paginação com filtros.
  • Objetos Page são serializados em um formato customizado com os campos content, size, totalElements, totalPages e number.
  • GET /formas-pagamento usa ETag e Cache-Control com cache de 10 segundos.
  • O projeto registra ShallowEtagHeaderFilter e libera CORS para todos os caminhos e métodos.

Formato de erro

Os erros da API seguem um payload padronizado com campos como:

  • status
  • type
  • title
  • detail
  • userMessage
  • timestamp
  • fields para erros de validação

Exemplo:

{
  "status": 400,
  "type": "https://algafood.com.br/dados-invalidos",
  "title": "Dados inválidos.",
  "detail": "Um ou mais campos estão inválidos. Corrija e informe os valores corretos e tente novamente.",
  "userMessage": "Um ou mais campos estão inválidos. Corrija e informe os valores corretos e tente novamente.",
  "timestamp": "2026-08-20T12:00:00Z",
  "fields": [
    {
      "name": "nome",
      "message": "Nome da cozinha é obrigatório"
    }
  ]
}

Testes

Os testes estão em src/test e hoje incluem principalmente um teste de integração para o recurso de cozinhas, usando:

  • @SpringBootTest com porta aleatória;
  • Rest Assured para chamadas HTTP reais;
  • DatabaseCleaner para limpar o banco entre execuções.

Banco de testes

O perfil test usa o banco:

  • jdbc:mysql://localhost:3306/algafood_test

Há um cuidado importante no DatabaseCleaner: ele só limpa bases cujo nome termina com test. Isso evita apagar dados de um banco de desenvolvimento por engano.

Rodando os testes

./mvnw test

No Windows PowerShell:

.\mvnw.cmd test

Observações práticas

  • A aplicação define o fuso padrão interno como UTC no main.
  • As mensagens de validação estão externalizadas em messages.properties, com textos em português.
  • O projeto já possui templates HTML para e-mail de confirmação e cancelamento de pedido.
  • O código usa repositórios customizados e Specification para filtros dinâmicos, especialmente em pedidos e restaurantes.
  • O perfil padrão injeta massa de dados automaticamente após as migrações, o que facilita testes manuais da API.

Resumo

Este projeto é uma API REST relativamente completa para estudo e evolução de um domínio de delivery/restaurantes. Ele já inclui boa parte da infraestrutura comum de aplicações reais: versionamento de banco, tratamento padronizado de erros, validações, paginação, filtros, cache HTTP, upload de arquivos, storage externo, eventos de domínio, templates de e-mail e documentação OpenAPI.

Para começar sem atrito, o melhor caminho costuma ser:

  1. subir um MySQL local;
  2. criar um perfil de desenvolvimento com email.impl=FAKE e storage.tipo=LOCAL;
  3. iniciar a aplicação com o Maven Wrapper;
  4. explorar a API pelo Swagger UI;
  5. usar os dados semeados automaticamente no perfil padrão para validar os fluxos.

About

Monolithic Application using DDD and Clean Code

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages