A production-oriented e-commerce backend portfolio project built with Java 21 and Spring Boot 4.
Quick start Β· Swagger Β· Architecture Β· Testing
Portfolio note: This README distinguishes implemented features from checks that still require a successful external Docker or GitHub Actions run.
| Capability | Implementation |
|---|---|
| Authentication | Stateless JWT, BCrypt passwords, method security |
| Authorization | User/admin role-based access control |
| Catalog | Products, categories, filtering, pagination |
| Commerce | Cart, orders, payments, reviews, addresses |
| Administration | User, product, category, order, dashboard APIs |
| Persistence | PostgreSQL, JPA/Hibernate, Flyway |
| Performance | Redis DTO caching and mutation invalidation |
| Quality | Unit, MockMvc, admin, and Testcontainers tests |
| Delivery | Multi-stage Docker image, Compose, GitHub Actions |
- Features
- Technology
- Architecture
- Quick start
- Configuration
- API documentation
- Authentication
- API surface
- Error contract
- Testing
- Operations and deployment
- CI
- Verification status
| π Security | JWT authentication, BCrypt, stateless sessions, method-level authorization, admin-only operations |
| ποΈ Commerce | Catalog browsing, cart management, order lifecycle, payment/refund flow, product reviews |
| β‘ Caching | Redis-backed product and category DTO caches with invalidation on mutations |
| π§ͺ Testing | JUnit 5, Mockito, MockMvc, PostgreSQL and Redis Testcontainers |
| π Documentation | OpenAPI 3, Swagger UI, examples, environment reference, Docker and CI instructions |
flowchart LR
Client[Web or API Client] --> Security[JWT Security Filter]
Security --> Controllers[REST Controllers]
Controllers --> Services[Transactional Services]
Services --> Repositories[Spring Data Repositories]
Repositories --> PostgreSQL[(PostgreSQL)]
Services <--> Cache[(Redis DTO Cache)]
Migrations[Flyway Migrations] --> PostgreSQL
The codebase uses a conventional layered architecture:
com.example.ecommerce
βββ config Security, Redis, cache, auditing, OpenAPI, request filters
βββ controller Public and admin HTTP endpoints
βββ dto Request and response contracts
βββ entity JPA entities and domain state
βββ exception Error contract and global exception handling
βββ repository Data access and product specifications
βββ security JWT validation and authenticated-user support
βββ service Business rules and transaction boundaries
PostgreSQL is the source of truth. Redis stores serialized response DTOs rather than managed JPA entities. Product and category mutations invalidate affected read caches, including filtered and paginated product results.
- JDK 21
- Docker Engine/Desktop with Compose
- Maven 3.9+ or the included Maven Wrapper
- Docker access for Testcontainers tests
docker compose up --buildServices:
| Service | Address | Purpose |
|---|---|---|
| API | http://localhost:8080 |
Spring Boot application |
| Swagger | http://localhost:8080/swagger-ui.html |
Interactive API docs |
| PostgreSQL | localhost:5432 |
Persistent relational data |
| Redis | localhost:6379 |
Cache and health contributor |
Stop services:
docker compose downUse docker compose down -v only when intentionally deleting local data volumes.
docker compose up -d postgres redis
./mvnw spring-boot:runLocal defaults are development-only. Supply production values through the environment:
| Variable | Description | Local default |
|---|---|---|
SPRING_DATASOURCE_URL |
PostgreSQL JDBC URL | jdbc:postgresql://localhost:5432/ecommerce |
SPRING_DATASOURCE_USERNAME |
Database username | ecommerce |
SPRING_DATASOURCE_PASSWORD |
Database password | ecommerce |
REDIS_HOST |
Redis hostname | localhost |
REDIS_PORT |
Redis port | 6379 |
JWT_SECRET |
JWT signing secret; use 32+ characters | Development placeholder |
SPRING_PROFILES_ACTIVE |
Optional active profile | unset |
Never commit real credentials, JWT secrets, .env files, or access tokens.
| Resource | URL |
|---|---|
| Swagger UI | /swagger-ui.html |
| OpenAPI JSON | /v3/api-docs |
| OpenAPI YAML | /v3/api-docs.yaml |
| Health | /actuator/health |
Swagger is configured with JWT Bearer authentication. Select Authorize and enter Bearer <access-token>.
Register and log in:
curl -X POST http://localhost:8080/api/v1/auth/register \
-H 'Content-Type: application/json' \
-d '{"name":"Ada Lovelace","email":"[email protected]","password":"StrongPassword123"}'
curl -X POST http://localhost:8080/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]","password":"StrongPassword123"}'Call a protected endpoint:
curl http://localhost:8080/api/v1/cart \
-H 'Authorization: Bearer <access-token>'| Domain | Base path | Access |
|---|---|---|
| Authentication | /api/v1/auth |
Public |
| Products | /api/v1/products |
Public reads; authenticated mutations |
| Categories | /api/v1/categories |
Public reads; authenticated mutations |
| Cart | /api/v1/cart |
Authenticated user |
| Orders | /api/v1/orders |
Authenticated user |
| Payments | /api/v1/orders/{orderId}/payment |
Authenticated user |
| Reviews | /api/v1/products/{productId}/reviews, /api/v1/reviews |
Authenticated user |
| Addresses | /api/v1/users/{userId}/addresses |
Authenticated owner |
| Admin users | /api/v1/admin/users |
Admin role |
| Admin products | /api/v1/admin/products |
Admin role |
| Admin categories | /api/v1/admin/categories |
Admin role |
| Admin orders | /api/v1/admin/orders |
Admin role |
| Dashboard | /api/v1/admin/dashboard |
Admin role |
Product listing supports name, category, status, minimum-price, maximum-price, pagination, and sorting parameters. Swagger is the authoritative source for exact schemas and parameter names.
{
"timestamp": "2026-10-20T12:00:00+02:00",
"status": 400,
"error": "VALIDATION_ERROR",
"message": "Request validation failed",
"path": "/api/v1/auth/register",
"correlationId": "7d3c0e7e-7dc1-4ad0-96e7-4ed8f2d3c2ab",
"fieldErrors": {"email": "must be a well-formed email address"}
}The application handles resource-not-found, business, validation, malformed-request, data-integrity, endpoint-not-found, and unexpected internal errors. A valid X-Correlation-Id is accepted; otherwise one is generated, returned, and placed in the logging context for the request.
# Full unit and integration suite
./mvnw test
# Redis/PostgreSQL Testcontainers class
./mvnw -Dtest=ProductCacheIntegrationTest test
# Compile/package without executing tests
./mvnw -DskipTests packageTestcontainers tests require a working Docker environment. Do not describe the full suite as green unless the exact command completes successfully.
The Dockerfile uses a Maven Java 21 build stage and Java 21 JRE runtime stage. Compose configures health checks for PostgreSQL and Redis, service-name networking, startup dependencies, and named persistence volumes.
For production deployment, add a non-root runtime user, external secret management, image scanning, TLS/reverse proxy configuration, resource limits, backups, and network policies.
.github/workflows/ci.yml runs on pushes to main/master and pull requests. It configures Java 21 and Maven caching, then runs ./mvnw -B verify. GitHub-hosted runners provide Docker for Testcontainers.
The workflow is configured in the repository; its success must be confirmed by an actual GitHub Actions run.
- Maven package build: verified with tests skipped.
- Swagger/OpenAPI dependency and application compilation: verified by package build.
- Unit and integration test suite: present, but the latest Redis cache run reported cache-population failures.
- Docker Compose end-to-end startup: not verified from this workspace.
- GitHub Actions execution: configured but not externally verified.
No license has been declared yet. Add an appropriate license before public distribution.