A Spring Boot microservices todo application with JWT authentication, service discovery, centralized configuration, and supporting infrastructure (MySQL, Redis, RabbitMQ).
flowchart LR
Client --> UserService
Client --> TodoService
UserService --> Eureka
TodoService --> Eureka
UserService --> ConfigServer
TodoService --> ConfigServer
TodoService -->|validate JWT| UserService
UserService --> MySQL
TodoService --> MySQL
UserService --> Redis
TodoService --> Redis
UserService --> RabbitMQ
TodoService --> RabbitMQ
| Module | Port | Role |
|---|---|---|
service-registry |
8761 | Eureka service discovery |
config-server |
8888 | Spring Cloud Config (native backend → config-repo/) |
user-service |
8083 | Registration, login, OTP verification, JWT issuance |
todo-service |
8082 | Todo CRUD with JWT validation via user-service |
Infrastructure (Docker Compose): MySQL 3306, Redis 6379, RabbitMQ 5672 / management UI 15672
- Java 17, Maven, Spring Boot 3
- Spring Cloud (Eureka, Config Server)
- Spring Security + JWT
- MySQL, Redis, RabbitMQ
- springdoc-openapi (Swagger UI)
- Java 17
- Maven 3.9+
- Docker Desktop (for MySQL, Redis, RabbitMQ)
copy .env.example .envEdit .env and set your own values. Use the same JWT_SECRET for both user-service and todo-service.
| Variable | Used by |
|---|---|
JWT_SECRET |
user-service, todo-service |
DB_USERNAME / DB_PASSWORD |
Spring services, Docker MySQL |
MYSQL_ROOT_PASSWORD |
Docker MySQL |
MAIL_USERNAME / MAIL_PASSWORD |
user-service (optional; mail disabled by default) |
docker compose up -dOn first run, MySQL creates the user_db and todo databases and applies todo.sql.
To reset the database (destroys data):
docker compose down -v
docker compose up -dStart each module from its directory with environment variables loaded from .env:
cd service-registry
mvn spring-boot:runcd config-server
mvn spring-boot:runcd user-service
mvn spring-boot:runcd todo-service
mvn spring-boot:runOn Windows PowerShell, load .env before starting a service:
Get-Content ..\.env | ForEach-Object {
if ($_ -match '^\s*([^#][^=]+)=(.*)$') { Set-Item -Path "env:$($matches[1].Trim())" -Value $matches[2].Trim() }
}
mvn spring-boot:runVerify Eureka at http://localhost:8761 — both user-service and todo-service should appear.
Swagger UI
- user-service: http://localhost:8083/swagger-ui.html
- todo-service: http://localhost:8082/swagger-ui.html
Typical flow
POST /api/v1/auth/register— create an accountPOST /api/v1/auth/activate/{email}?otp=...— verify OTP (printed to console whenapp.mail.enabledisfalse)POST /api/v1/auth/login— receive a JWT- On todo-service Swagger, click Authorize and paste
Bearer <token> - Use the todo CRUD endpoints
Runtime config is centralized in config-repo/ and served by the config server. Each service bootstraps with:
spring.config.import: optional:configserver:http://localhost:8888Secrets (JWT_SECRET, database credentials) are not committed. They are referenced as environment variables in config-repo/user-service.yml and config-repo/todo-service.yml.
cd user-service
mvn test
cd todo-service
mvn testTests use an in-memory H2 database and do not require Docker.
TodoApp/
├── config-repo/ # Centralized Spring Cloud Config files
├── config-server/ # Config server (port 8888)
├── service-registry/ # Eureka server (port 8761)
├── user-service/ # Auth service (port 8083)
├── todo-service/ # Todo API (port 8082)
├── docker-compose.yml # MySQL, Redis, RabbitMQ
├── todo.sql # Todo schema (applied on first MySQL init)
└── .env.example # Template for local secrets