Este repositório documenta a construção de uma API REST para gerenciamento de eventos, a EventFlow API. Mais do que um projeto, este é um case de estudo prático sobre a aplicação de princípios de arquitetura de software moderna, como Domain-Driven Design (DDD) e Arquitetura Limpa (Clean Architecture), em um ambiente Spring Boot.
A EventFlow API tem como objetivo fornecer um backend robusto para uma plataforma de eventos, permitindo o cadastro de usuários (organizadores e participantes), criação e gerenciamento de eventos, e reserva de ingressos. O foco principal deste projeto não é apenas a funcionalidade, mas a jornada arquitetural, documentando as decisões tomadas para garantir que a aplicação seja escalável, testável, segura e de fácil manutenção.
- Linguagem e Framework: Java 21, Spring Boot 3
- Persistência: Spring Data JPA, Hibernate, PostgreSQL
- Segurança: Spring Security 6, Autenticação e Autorização com JWT
- Testes: JUnit 5, Testcontainers (para testes de integração com banco de dados real)
- Comunicação Assíncrona: Spring WebFlux (
WebClientpara APIs externas),@Async - Tarefas Agendadas: Spring Sheduling (
@Scheduled) - Arquitetura: Domain-Driven Design (DDD), Arquitetura Limpa, Padrão de Repositório, Use Cases, Mappers.
- Concorrência: Controle de Concorrência Otimista com
@Version.
Este projeto foi fortemente influenciadas por conceitos consolidados na indústria de software e pela documentação oficial das ferramentas utilizadas.
-
Domain-Driven Design (DDD): A principal filosofia de design do projeto foi baseada nos conceitos apresentados por Eric Evans, focando em um modelo de domínio rico e desacoplado da infraestrutura.
- Evans, Eric. Domain-Driven Design: Atacando as Complexidades no Coração do Software. Addison-Wesley, 2003.
-
Arquitetura Limpa: A estrutura de camadas (Domain, Application, Infrastructure, Presentation) é uma adaptação direta dos princípios da Arquitetura Limpa, popularizada por Robert C. Martin, que prega a separação de responsabilidades e a independência de frameworks.
- Martin, Robert C. Arquitetura Limpa: o Guia do Artesão Para Estrutura e Design de Software. Prentice Hall, 2017.
-
Commits Semânticos: A organização do histórico de versionamento seguiu o padrão de Conventional Commits, que ajuda a tornar os commits mais explícitos e fáceis de entender.
A maior parte da implementação técnica foi guiada diretamente pela documentação oficial das tecnologias.
-
Spring Framework: A documentação do Spring foi a principal referência para todos os módulos utilizados.
-
Java Platform (JDK): A documentação oficial do Java para consulta de funcionalidades da linguagem e APIs padrão.
-
JPA & Hibernate: Para entender os detalhes de persistência, mapeamento de entidades e o funcionamento do bloqueio otimista.
-
Testes (JUnit 5 & Testcontainers):
-
Outras Ferramentas e Padrões:
Este projeto foi construído de forma incremental, com cada passo validando uma parte da arquitetura.
Adotei uma arquitetura limpa dividida em quatro camadas principais:
- domain: Contém as entidades de negócio (POJOs), regras de negócio, serviços de domínio e as interfaces dos repositórios. É uma camada pura, sem dependências de frameworks externos como JPA ou Spring.
- application: Contém os
UseCasesque representam as ações que o sistema pode realizar. Ele coordena a busca de dados (através das interfaces de repositório) e a execução da lógica de negócio (chamando as entidades de domínio). - infrastructure: Contém as implementações das interfaces do domínio. Aqui estão os repositórios JPA, clientes de APIs externas (
WebClient), serviços de e-mail e outras tecnologias. - presentation: Contém os Controllers da API REST, DTOs e o tratamento global de exceções.
Inicialmente, para acelerar a construção da primeira funcionalidade (cadastro/login), adotei um modelo híbrido onde as entidades de domínio (User) eram também as entidades de persistência (anotadas com @Entity).
Após validar a base, evoluímos para uma abordagem DDD mais pura:
- Entidades de Domínio puras: As classes em domain/entity foram "limpas" de todas as anotações do JPA.
- Modelos de persistência: Criei classes Model na camada de infraestrutura, que são a representação exata das tabelas do banco e contêm as anotações do JPA.
- Mappers: Implementei
Mapperspara fazer a "tradução" entre os objetos de domínio e os modelos de persistência, fiz para garantir total desacoplamento do domínio.
Para resolver o problema de "condições de corrida" (ex: dois usuários tentando comprar o último ingresso), implementei o bloqueio otimista.
- @Version: Adicionei um campo
versionnas entidades de persistência. O JPA o utiliza automaticamente para garantir que uma atualização só ocorra se a versão do objeto não tiver sido alterada por outra transação. - Validação com Teste Automatizado: Criei um teste de integração (
ReserveTicketUseCaseConcurrencyTest) que usa múltiplas threads (ExecutorService) para simular uma condição de corrida real e validar que uma das transações falha comObjectOptimisticLockingFailureException, provando que o mecanismo funciona.
Para a funcionalidade de notificação de clima:
- Cliente reativo: Usei o
WebClientpara fazer chamadas assíncronas e não bloqueantes à API externa. - Processos em background:
@Async, o serviço de envio de e-mails foi marcado como assíncrono para não travar a thread principal da requisição, e o@Scheduled, o job que orquestra todo o processo de notificação foi implementado com um agendador para rodar automaticamente.
Este projeto foi desenvolvido dentro de um ambiente academico. As escolhas de tecnologias e as metodologias de trabalho seguiram tanto as diretrizes de livros academicos quanto critérios pessoais de eficiência e familiaridade. Devido ao meu tempo limitado, algumas funcionalidades podem estar inacabados, apresentar bugs ou comportamentos inesperados. Relatórios de issues, sugestões de melhorias e contribuições são muito bem-vindos!