Skip to content

Latest commit

 

History

50 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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