A learning platform for exploring microservice architecture with Java/Spring Boot, Temporal workflows, and a full observability stack.
micro-system/
├── services/
│ ├── user-service/ # user management
│ ├── inventory-service/ # products and stock
│ └── order-service/ # orders + Place Order saga (Temporal)
├── apps/storefront/ # Next.js online store
├── load-tests/ # k6 scenarios (through Kong)
└── k8s-env/ # k3d manifests, configs and Tiltfile
| Service | Port | Description |
|---|---|---|
user-service |
8080 | User CRUD and lifecycle management |
inventory-service |
8081 | Product catalog and inventory stock |
order-service |
8082 | Order placement orchestrated via Temporal saga |
order-service runs a distributed transaction across services using Temporal:
createOrder → reserveStock → processPayment → commitReservation → confirmOrder
↓ ↓ ↓
cancelOrder releaseReservation refundPayment
Each step has a compensating transaction. On failure Temporal executes them in reverse order automatically.
| Component | Port | Purpose |
|---|---|---|
| Grafana | 3000 | Dashboards (metrics, logs, traces) |
| Prometheus | 9090 | Metrics collection |
| Loki | 3100 | Log aggregation |
| Tempo | 3200 | Distributed tracing (OTLP) |
| Grafana Alloy | — | Pod log collector (k8s API → Loki) |
| Temporal | 7233 | Workflow orchestration |
| Temporal UI | 8088 | Workflow visibility |
- Java 25, Spring Boot 4.1.1
- Gradle (build), Lombok (code generation), Flyway (migrations)
- Temporal (
io.temporal:temporal-sdk) for distributed saga workflows - k3d (local Kubernetes) + Tilt (image builds, deploys, port-forwards)
- Keycloak (identity provider), Kong (API gateway)
- OpenTelemetry (tracing), Micrometer + Prometheus (metrics)
- springdoc (OpenAPI / Swagger UI)
- Java 25+
- Docker Desktop
- Tilt,
k3d,kubectl(brew install k3d kubectl) gitleaksandyamllintfor pre-commit hooks (brew install gitleaks yamllint)
cd services/user-service
./gradlew installGitHooksCreate the local registry and cluster once:
k3d registry create micro-system-registry --port 5001
k3d cluster create micro-system --registry-use k3d-micro-system-registry:5001 \
-p "127.0.0.1:80:80@loadbalancer"
cp apps/storefront/.env.local.example apps/storefront/.env.localThen:
cd k8s-env
tilt upTilt builds the service images, deploys everything into the micro-system namespace and exposes it through the Traefik ingress on port 80. See k8s-env/README.md.
| Resource | URL |
|---|---|
| API (Kong) | http://api.micro.localhost |
| API docs | http://api.micro.localhost/docs |
| Storefront | http://app.micro.localhost |
| Keycloak | http://auth.micro.localhost |
| Temporal UI | http://temporal.micro.localhost |
| Grafana | http://grafana.micro.localhost |
| Prometheus | http://prometheus.micro.localhost |
Backend services are reached through Kong (/users, /products, /orders).
| Method | Path | Description |
|---|---|---|
POST |
/users |
Create a user (PENDING) |
GET |
/users |
List users (paginated) |
GET |
/users/{id} |
Get user |
PATCH |
/users/{id} |
Update name / phone |
DELETE |
/users/{id} |
Delete user |
POST |
/users/{id}/activate |
PENDING → ACTIVE |
POST |
/users/{id}/suspend |
ACTIVE → SUSPENDED |
POST |
/users/{id}/close |
→ CLOSED (terminal) |
GET |
/users/{id}/preferences |
Get preferences |
PUT |
/users/{id}/preferences |
Replace preferences |
| Method | Path | Description |
|---|---|---|
POST |
/products |
Create product with initial stock |
GET |
/products/{id} |
Get product |
| Method | Path | Description |
|---|---|---|
POST |
/orders |
Place order — starts Temporal saga (202) |
GET |
/orders/{id} |
Get order status |