Este repositório contém o back-end desenvolvido utilizando Spring Framework para atender aos requisitos do desafio.
- Como Executar o projeto
- Modularização
- Autenticação Stateless
- Otimizações no Banco de Dados
- Modulo Para Reutilização de Código
- Tratamento de Erros
- Regras de Negócio
Important
Este repositório cotém video de demonstação da execução e endpoints via postman. Pode ser encontrado em ./docs/video/demonstracao-api-ecommerce.mp4
O arquivo docker-compose.yml contem as declarações e configurações para disponibilizar uma instancia do banco de dados MySql, bastar executar o comando.
Warning
Antes de iniciar a aplicação realize a criação das tabelas (DDL) e adição do registros (DML) importando o arquivo dump.sql.
docker-compose.ymlNote
Tambem é possivel utilizar o banco de dados configurado localmente
As configurações de conexão com o banco de dados podem ser definidas nas seguintes variaveis de ambiente:
- SPRING_DATASOURCE_URL: URL de conexão do banco de dados (padrão: jdbc:mysql://localhost:3306/e_commerce_db)
- SPRING_DATASOURCE_USERNAME (padrão: root)
- SPRING_DATASOURCE_PASSWORD (padrão: root)
Tip
Ao executar os containers definidos no docker compose, nenhuma variável de ambiente precisa ser definida, basta apenas executar a aplicação.
Utilize a Postman Colletcion com os endpoints para realizar testes na aplicação.
Para executar aplicação Api Ecommerce no diretório do modulo principal ./ecommerce/ execute:
.\mvnw spring-boot:runO projeto esta divido em três modulos:
securitypaymentecommerce
afim de manter a coesão de código e manter as responsabilidades bem definidas.
O método de autenticação utilizado no projeto é stateless com token JWT
no interior do token estão contidos as seguintes claims:
- id: identificar o usuario.
- role: verificar quais recursos podem ser acessados.
Foram feitas as otimizações afim de obter melhor performance no processamento das requisições.
-
Tipo do campo Id (UUID) das tabelas definido para BINARY(16).
- Ocupa menos espaço em disco.
- Necessita de menos processamento para comparações.
-
Utilizar indices para reduzir a quantidade de linhas lidas na tabelas pela clausula COUNT utilizando o campo id (COUNT(p.id)).
<query> <![CDATA[ SELECT u.id AS id, u.nome AS nome, u.email AS email, COUNT(p.id) AS totalPedidos FROM pedido p JOIN usuario u ON p.usuario_id = u.id GROUP BY u.id ORDER BY totalPedidos DESC LIMIT :quantidade ]]> </query>
-
Uso de JOIN FETCH para unificar tabelas evitando N+1 Queries.
-
Criação de Indices para os campo mais utilizados para pesquisa.
@Entity @Table(name = "usuario", indexes = {@Index(name = "idx_usuario_email", columnList = "email")}) public class Usuario extends Identity<UUID> { ... }
@Entity @Table(indexes = { @Index(name = "idx_pedido_usuario", columnList = "usuario_id"), @Index(name = "idx_created_at", columnList = "createdAt") }) @Getter @Setter public class Pedido extends AuditableEntity<UUID> { ... }
A aplicação possui o módulo para reutilização de código e implementação dos padrões de projeto Strategy e Template Method.
- Desenvolvimento de Arquitetura Hexagonal Limpa (Clean Code, KISS).
- Implementação de CRUD com reutilização de código (foco no desenvolvimento das regras de negócio).
- Geração de documentação automática utilizando Swagger.
- Configuração automática para gerenciamento de exceptions e formatação para RFC7807 (Norma para padronização de retorno de erros em Rest Apis).
Important
A documentação do módulo foi desenvolvida utilizando Quarkus, porém, os exemplos são aplicados de forma similar no Spring. Esta pode ser encontrada em Trajy/Quarkus Base Architecture.
O módulo está no repositório Trajy/Spring-Base-Architecture e foi adicionado ao projeto utilizando Maven como gerenciador de dependências.
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.Trajy</groupId>
<artifactId>Spring-Api-Architecture</artifactId>
<version>main-SNAPSHOT</version>
</dependency>
</dependencies>Important
O desenvolvedor pode focar no desenvolvimento das regras de negócio.
A configuração do gerenciador de exceptions pode ser feita de forma simples:
import br.com.trajy.architecture.restful.exception.RestGlobalExecptionHandler;
@Import({
RestGlobalExecptionHandler.class //Configura o gerenciador de exceptions
})
@Configuration
public class AutoConfigurations {
}Exemplo de resposta de erro conforme o padrão RFC7807:
{
"status": "401",
"type": "/usuario/auth",
"detail": "Usuário inexistente ou senha inválida."
}A transição entre os status do pedido foi desenvolvida utilizando o Design Pattern Strategy. Com essa abordagem é possivel controlar quais as alterações possiveis:
Note
Se houver a tentativa de alterar o status de ENVIADO para CANCELADO a operação não será permitida. De forma análoga demais alterações no status que não atendam o fluxo no diagrama não serão permitidas.
