API RESTful para gerenciamento de loja de jogos, implementando padrão de arquitetura , segurança JWT, migrations com Flyway e documentação Swagger. O projeto demonstra boas práticas de desenvolvimento backend com Spring Boot 3, validações robustas, logs estruturados e containerização Docker.
- ✅ Autenticação e Autorização: JWT com roles (USER/ADMIN)
- ✅ Gestão de Produtos: CRUD completo com filtros avançados e paginação
- ✅ Sistema de Categorias: Organização de produtos por categorias ativas
- ✅ Sistema de Avaliações: Notas (1-5) e comentários por usuário
- ✅ Lista de Favoritos: Produtos favoritos por usuário
- ✅ Carrinho de Compras: Gestão de itens com cálculo de subtotais e descontos
- ✅ Migrations Flyway: Versionamento de schema do banco de dados
- ✅ Validações de Negócio: Regras complexas com Bean Validation
- ✅ Logs Estruturados: Logback com rotação de arquivos
- ✅ Documentação API: Swagger/OpenAPI 3.0
- Java 17 - Linguagem de programação
- Spring Boot 3.2.0 - Framework principal
- Spring Security 6 - Autenticação e autorização
- Spring Data JPA - Persistência de dados
- Hibernate - ORM
- MySQL 8.0 - Banco de dados relacional
- Flyway 9.22 - Versionamento de schema
- JWT (JJWT 0.11.5) - Tokens de autenticação
- BCrypt - Hash de senhas
- Bean Validation - Validações de entrada
- Swagger/OpenAPI 3.0 - Documentação interativa
- Springdoc OpenAPI 2.0.2 - Integração Swagger
- Docker & Docker Compose - Containerização
- Maven - Gerenciamento de dependências
- Logback - Sistema de logs com rotação
- SonarQube - Análise de qualidade de código
spring-gamestore/
├── src/main/java/com/energygames/lojadegames/
│ ├── configuration/ # Configurações gerais
│ │ └── SwaggerConfig.java # Documentação OpenAPI
│ ├── controller/ # REST Controllers
│ │ ├── CategoriaController.java
│ │ ├── ProdutoController.java
│ │ ├── UsuarioController.java
│ │ ├── AvaliacaoController.java
│ │ ├── FavoritoController.java
│ │ └── CarrinhoController.java
│ ├── dto/ # Data Transfer Objects
│ │ ├── mapper/ # Conversores Entity-DTO
│ │ ├── request/ # DTOs de entrada
│ │ └── response/ # DTOs de saída
│ ├── exception/ # Tratamento de exceções
│ │ ├── GlobalExceptionHandler.java
│ │ ├── ResourceNotFoundException.java
│ │ ├── BusinessRuleException.java
│ │ └── ...
│ ├── model/ # Entidades JPA
│ │ ├── Usuario.java
│ │ ├── Categoria.java
│ │ ├── Produto.java
│ │ ├── Avaliacao.java
│ │ ├── Favorito.java
│ │ └── CarrinhoItem.java
│ ├── repository/ # Repositórios JPA
│ │ ├── UsuarioRepository.java
│ │ ├── CategoriaRepository.java
│ │ ├── ProdutoRepository.java
│ │ ├── AvaliacaoRepository.java
│ │ ├── FavoritoRepository.java
│ │ └── CarrinhoRepository.java
│ ├── security/ # Segurança JWT
│ │ ├── BasicSecurityConfig.java
│ │ ├── JwtAuthFilter.java
│ │ ├── JwtService.java
│ │ └── UserDetailsServiceImpl.java
│ ├── service/ # Lógica de negócio
│ │ ├── impl/ # Implementações
│ │ ├── UsuarioService.java
│ │ ├── CategoriaService.java
│ │ ├── ProdutoService.java
│ │ ├── AvaliacaoService.java
│ │ ├── FavoritoService.java
│ │ └── CarrinhoService.java
│ └── enums/ # Enumerações
│ └── RoleEnum.java
├── src/main/resources/
│ ├── db/migration/ # Scripts Flyway
│ │ └── V1__initial_schema.sql
│ ├── application.properties
│ └── logback-spring.xml # Configuração de logs
├── docker-compose.yml # Orquestração de containers
├── Dockerfile # Imagem Docker da aplicação
├── pom.xml # Dependências Maven
└── README.md
- Java 17 ou superior
- Maven 3.8+
- MySQL 8.0 (ou use Docker Compose)
- Docker & Docker Compose (opcional, mas recomendado)
- Clone o repositório
git clone https://github.com/growthfolio/spring-gamestore.git
cd spring-gamestore- Configure as variáveis de ambiente
cp .env.example .env
# Edite o arquivo .env com suas configurações- Inicie os containers
docker-compose up -dA aplicação estará disponível em http://localhost:8080
- Clone o repositório
git clone https://github.com/growthfolio/spring-gamestore.git
cd spring-gamestore- Configure o MySQL
CREATE DATABASE db_lojadegames CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- Configure o
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/db_lojadegames?createDatabaseIfNotExist=true
spring.datasource.username=seu_usuario
spring.datasource.password=sua_senha- Execute as migrations do Flyway
./mvnw flyway:migrate- Compile e execute o projeto
./mvnw clean install
./mvnw spring-boot:runA aplicação estará disponível em http://localhost:8080
Após iniciar a aplicação, acesse a documentação interativa do Swagger:
http://localhost:8080/swagger-ui.html
POST /usuarios/cadastrar
Content-Type: application/json
{
"nome": "João Silva",
"usuario": "joao@email.com",
"senha": "senha123",
"foto": "https://i.imgur.com/exemplo.jpg"
}POST /usuarios/logar
Content-Type: application/json
{
"usuario": "joao@email.com",
"senha": "senha123"
}POST /produtos
Authorization: Bearer {seu_token_jwt}
Content-Type: application/json
{
"nome": "The Legend of Zelda: Breath of the Wild",
"descricao": "Aventura épica em mundo aberto",
"preco": 299.99,
"desconto": 10.00,
"estoque": 50,
"plataforma": "Nintendo Switch",
"desenvolvedor": "Nintendo EPD",
"publisher": "Nintendo",
"dataLancamento": "2017-03-03",
"imagens": ["https://exemplo.com/imagem1.jpg"],
"ativo": true,
"categoria": {
"id": 1
}
}GET /produtos?nome=zelda&plataforma=Nintendo%20Switch&page=0&size=10&sort=nome,ascPOST /avaliacoes
Authorization: Bearer {seu_token_jwt}
Content-Type: application/json
{
"nota": 5,
"comentario": "Jogo incrível! Melhor experiência em mundo aberto.",
"produtoId": 1
}POST /carrinho
Authorization: Bearer {seu_token_jwt}
Content-Type: application/json
{
"produtoId": 1,
"quantidade": 2
}# Executar todos os testes
./mvnw test
# Executar testes com coverage
./mvnw clean test jacoco:report
# Pular testes durante o build
./mvnw clean install -DskipTestsOs logs da aplicação são armazenados em:
- Console: Logs em tempo real durante desenvolvimento
- Arquivo:
/logs/spring-gamestore.log(rotação automática a cada 10MB, mantém 30 dias)
- ERROR: Erros críticos da aplicação
- WARN: Avisos e situações anormais
- INFO: Informações importantes de operação
- DEBUG: Detalhes de debug (apenas em desenvolvimento)
- Token válido por: 1 hora (configurável via
JWT_EXPIRATION) - Algoritmo: HS256
- Senha: Hash BCrypt com salt
- USER: Acesso a endpoints de consulta e operações pessoais
- ADMIN: Acesso completo, incluindo gestão de produtos e categorias
POST /usuarios/cadastrar- Registro de usuárioPOST /usuarios/logar- LoginGET /swagger-ui.html- Documentação
Requerem header Authorization: Bearer {token}
docker build -t gamestore-api .docker run -p 8080:8080 \
-e SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3306/db_lojadegames \
-e SPRING_DATASOURCE_USERNAME=root \
-e SPRING_DATASOURCE_PASSWORD=root \
gamestore-api# Iniciar todos os serviços
docker-compose up -d
# Ver logs
docker-compose logs -f app
# Parar serviços
docker-compose down
# Limpar volumes (CUIDADO: apaga dados do banco)
docker-compose down -vsrc/main/resources/db/migration/
└── V1__initial_schema.sql
- Versão:
V{número}__descrição.sql(ex:V1__initial_schema.sql) - Repeatable:
R__script_repetível.sql
# Ver status das migrations
./mvnw flyway:info
# Executar migrations pendentes
./mvnw flyway:migrate
# Limpar banco (CUIDADO: apaga tudo)
./mvnw flyway:clean
# Validar migrations
./mvnw flyway:validateO projeto está integrado com SonarQube para análise de qualidade. Veja QUICKSTART_SONAR_SYNC.md para instruções.
- ✅ DTOs para separação de camadas
- ✅ Service Layer para lógica de negócio
- ✅ Repository Pattern para acesso a dados
- ✅ Exception Handling centralizado
- ✅ Validações com Bean Validation
- ✅ Logs estruturados
- ✅ Migrations versionadas
- ✅ Documentação OpenAPI
- ✅ Código organizado e coeso
- Sistema de autenticação JWT
- Gestão de usuários com roles
- CRUD de categorias
- CRUD de produtos com filtros
- Sistema de avaliações (notas e comentários)
- Lista de favoritos
- Carrinho de compras
- Migrations Flyway
- Docker Compose
- Documentação Swagger
- Processamento de pedidos
- Integração com gateway de pagamento
- Sistema de cupons de desconto
- Notificações por email
- Dashboard administrativo
- Relatórios de vendas
- Sistema de recomendações
- Wishlist pública
- Testes de integração completos
- Controller: Recebe requisições HTTP e retorna respostas
- Service: Contém lógica de negócio e validações
- Repository: Acesso e persistência de dados
- Model: Entidades JPA mapeadas para o banco
- JWT: Autenticação stateless com tokens
- BCrypt: Hash seguro de senhas
- CORS: Controle de acesso de origens cruzadas
- HTTPS: Comunicação segura (configurável para produção)
- JPA/Hibernate: ORM para mapeamento objeto-relacional
- Flyway: Migrations versionadas
- Transactions: Garantia de consistência (ACID)
- Lazy/Eager Loading: Otimização de queries
- Paginação: Consultas otimizadas com Spring Data
- Índices: Otimização de queries no banco
- Caching: Second-level cache do Hibernate
- Connection Pool: HikariCP para gerenciamento de conexões
Contribuições são bem-vindas! Para contribuir:
- Fork o projeto
- Crie uma branch para sua feature (
git checkout -b feature/NovaFuncionalidade) - Commit suas mudanças (
git commit -m 'Adiciona nova funcionalidade') - Push para a branch (
git push origin feature/NovaFuncionalidade) - Abra um Pull Request
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
Energy Games Team
- GitHub: @felipemacedo1
- LinkedIn: Felipe Macedo
Para dúvidas ou sugestões:
- Abra uma issue
- Entre em contato: contato@energygames.com
⭐ Se este projeto foi útil para você, considere dar uma estrela!
Desenvolvido com ❤️ usando Spring Boot
- Price management: Gestão de preços e promoções
- JWT Authentication: Autenticação baseada em tokens
- Role-based access: Controle de acesso por perfis
- Password encryption: Criptografia de senhas
- CORS configuration: Configuração para frontend
- API security: Proteção de endpoints sensíveis
- JPA relationships: Relacionamentos OneToMany/ManyToOne
- Query optimization: Consultas otimizadas
- Transaction management: Controle transacional
- Data validation: Validação de dados de entrada
- Error handling: Tratamento consistente de erros
@Entity
@Table(name = "games")
public class Game {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String nome;
@Column(columnDefinition = "TEXT")
private String descricao;
@Column(nullable = false, precision = 10, scale = 2)
private BigDecimal preco;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "categoria_id")
private Category categoria;
// Constructors, getters, setters
}
@Entity
@Table(name = "categories")
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String nome;
@OneToMany(mappedBy = "categoria", cascade = CascadeType.ALL)
private List<Game> games = new ArrayList<>();
}@RestController
@RequestMapping("/api/games")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class GameController {
@Autowired
private GameService gameService;
@GetMapping
public ResponseEntity<List<Game>> getAll() {
return ResponseEntity.ok(gameService.findAll());
}
@GetMapping("/{id}")
public ResponseEntity<Game> getById(@PathVariable Long id) {
return gameService.findById(id)
.map(game -> ResponseEntity.ok(game))
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<Game> create(@Valid @RequestBody Game game) {
Game savedGame = gameService.save(game);
return ResponseEntity.status(HttpStatus.CREATED).body(savedGame);
}
@GetMapping("/categoria/{categoria}")
public ResponseEntity<List<Game>> getByCategory(@PathVariable String categoria) {
List<Game> games = gameService.findByCategoriaNomeContainingIgnoreCase(categoria);
return ResponseEntity.ok(games);
}
}@Service
public class GameService {
@Autowired
private GameRepository gameRepository;
@Autowired
private CategoryService categoryService;
public List<Game> findAll() {
return gameRepository.findAll();
}
public Optional<Game> findById(Long id) {
return gameRepository.findById(id);
}
@Transactional
public Game save(Game game) {
// Validar categoria
if (game.getCategoria() != null && game.getCategoria().getId() != null) {
Category categoria = categoryService.findById(game.getCategoria().getId())
.orElseThrow(() -> new EntityNotFoundException("Categoria não encontrada"));
game.setCategoria(categoria);
}
return gameRepository.save(game);
}
public List<Game> findByCategoriaNomeContainingIgnoreCase(String categoria) {
return gameRepository.findByCategoriaNomeContainingIgnoreCase(categoria);
}
}- Data modeling: Modelagem eficiente de relacionamentos
- Performance: Otimização de queries com JPA
- Security: Implementação robusta de autenticação
- Error handling: Tratamento consistente de exceções
- Testing: Cobertura adequada de testes
- Spring Boot Reference
- Spring Data JPA
- Spring Security
- E-commerce Best Practices
- Generation Brasil Bootcamp - Bootcamp onde o projeto foi desenvolvido
- Implementar sistema de carrinho de compras
- Adicionar sistema de avaliações
- Criar sistema de recomendações
- Implementar processamento de pagamentos
- Adicionar sistema de cupons de desconto
- Criar dashboard administrativo
- React GameStore Front - Frontend da aplicação
Desenvolvido por: Felipe Macedo
Contato: contato.dev.macedo@gmail.com
GitHub: FelipeMacedo
LinkedIn: felipemacedo1
💡 Reflexão: Este projeto consolidou conhecimentos em desenvolvimento de APIs REST para e-commerce. A implementação de relacionamentos JPA e sistema de autenticação proporcionou experiência prática em arquiteturas backend robustas.