Esta API RESTful foi desenvolvida em Java 17 com Spring Boot 3 e tem como objetivo gerenciar lançamentos bancários de débito e crédito. Suporta múltiplos lançamentos por requisição, controle de concorrência pessimista para garantir a integridade dos dados.
- Java 17
- Spring Boot 3
- Swagger
- Spring Data JPA
- PostgreSQL (produção/desenvolvimento)
- Maven
- JUnit 5 + Mockito (testes)
- ✅ Cadastro de lançamentos (débito e crédito)
- 🔁 Suporte a múltiplos lançamentos por requisição
- ✅ Transferência de dinheiro entre contas
- 🔒 Controle de concorrência pessimista
- 🧾 Consulta de saldo
- 🧪 Testes unitários
A arquitetura da aplicação segue o padrão Layered Architecture (Arquitetura em Camadas), onde cada camada tem uma responsabilidade bem definida, proporcionando uma melhor organização e manutenção do código. As camadas principais são:
A camada de Models contém as entidades que representam as tabelas do banco de dados. Cada entidade é anotada com as anotações do JPA, como @Entity e @Id, para definir a estrutura das tabelas e as relações entre elas.
- Exemplo:
Account,Transfer,Bank, etc.
A camada de Repositories é responsável pela interação direta com o banco de dados. Os repositórios utilizam o Spring Data JPA, estendendo a interface JpaRepository, o que proporciona métodos prontos para operações CRUD (Create, Read, Update, Delete) e consultas customizadas.
- Exemplo:
AccountRepository,TransferRepository, etc.
A camada de Service contém a lógica de negócio da aplicação. É nela que você implementa as regras e processos, como validações, cálculos, e manipulação dos dados entre o Controller e o Repository. A camada de serviço é uma abstração da lógica de negócios e serve como intermediária entre o Controller e o Repository.
- Exemplo:
AccountService,TransferService, etc.
A camada de Controller é responsável por expor os endpoints da API REST. Ela recebe as requisições HTTP, delega a lógica para a camada de Service, e retorna a resposta apropriada ao cliente. O Controller é responsável apenas por gerenciar as requisições e não contém lógica de negócio.
- Exemplo:
AccountController
Os DTOs, Requests e Responses são utilizados para transferir dados entre as camadas da aplicação de forma mais eficiente e segura. Eles evitam o acoplamento direto entre a camada de Controller e Model, permitindo a conversão de dados de forma controlada. Geralmente, você terá DTOs para requisições (Request) e respostas (Response).
- Exemplo:
AccountDto,TransferResponse, etc.
O ControllerAdvice é usado para tratar exceções globalmente e gerar respostas consistentes para erros. Ele permite capturar exceções específicas (como InsufficientBalanceException, AccountNotFoundException, etc.) e retornar um erro HTTP com a mensagem apropriada.
- Exemplo:
InsufficientBalanceExceptionHandlerque trata o erro de saldo insuficiente e lança respostas personalizadas.
Quando uma requisição chega na API, ela passa pelo Controller, que delega a execução da lógica para o Service. O Service interage com o Repository para buscar ou manipular os dados e, por fim, retorna uma response que será enviada como resposta ao cliente. Se ocorrer algum erro, ele será tratado pelo ControllerAdvice, que garante uma resposta consistente para o usuário.
- Separação de responsabilidades: Cada camada tem uma responsabilidade clara, facilitando a manutenção e evolução do código.
- Facilidade de testes: Cada camada pode ser testada de forma isolada.
- Escalabilidade: A arquitetura facilita a adição de novas funcionalidades sem impactar demais as camadas existentes.
- Java 17
- Maven 3.9.9
- Docker
- Docker Compose
Antes de rodar a aplicação, é necessário iniciar o banco de dados PostgreSQL com Docker Compose. Execute o seguinte comando na raiz do projeto:
docker-compose -f docker-compose.dev.yml up -d
Para iniciar a aplicação é preciso rodar o comando mvn spring-boot:run na raiz do projeto,
esse comando irá iniciar a aplicação com o perfil 'dev', com esse perfil ativo será gerado dados iniciais no banco de dados.
- Exemplo:
Bank,Account,Agency, etc.
- Essa configuração está na classe .../com.marcelohofart.bank_api/configs/DatabaseSeeder.java
Após iniciar a aplicação, será gerado uma URL do swagger-ui que irá direcionar para a documentação dos endpoints.
- URL:
http://localhost:8080/swagger-ui.html
Para realizar todos os testes unitários da aplicação, na raiz do projeto utilize o comando Maven:
mvn test
Para adicionar novas funcionalidades à API, siga os passos abaixo respeitando a estrutura e boas práticas do projeto:
-
Model (Entidade)
Crie a classe no pacotemodelscom as anotações do JPA (@Entity,@Id, etc). -
Repository
Crie uma interface no pacoterepositoriesestendendoJpaRepository. -
DTOs
Crie os DTOs nos pacotesdtos, requests, responsespara representar os dados de entrada e saída. -
Service
No pacoteservices, implemente a regra de negócio, fazendo as conversões entre DTOs e entidades. -
Controller
Crie o endpoint REST no pacotecontroller, chamando os métodos da camada de serviço. -
Testes
Adicione testes unitários.
✅ Mantenha o padrão de organização do projeto e evite regras de negócio diretamente nos controllers.
A aplicação utiliza o padrão @ControllerAdvice para capturar e tratar exceções de forma centralizada, garantindo respostas consistentes e personalizadas para os erros. O RestExceptionHandler intercepta as exceções lançadas pela aplicação e retorna uma mensagem de erro específica para cada tipo de exceção.
-
InsufficientBalanceException
Retorna um erro400 Bad Requestcom a mensagem de saldo insuficiente. -
AccountNotFoundException
Retorna um erro404 Not Foundquando a conta não for encontrada. -
IllegalArgumentException
Retorna um erro400 Bad Requestquando os argumentos fornecidos são inválidos. -
InvalidTransactionRequestException
Retorna um erro400 Bad Requestpara requisições de transações inválidas. -
InvalidTransferRequestException
Retorna um erro400 Bad Requestpara requisições de transferências inválidas.