π Advanced Microservices Architecture - Practical Assignments
E-Commerce Platform Migration Projectβ
Course: Advanced Microservices Architecture
Version: 1.1.0
Last Updated: 2026-01-13
Prerequisite: Completed mono-src (Building High-Performance APIs with FastAPI)
π― Project Overviewβ
Migration Journeyβ
You will migrate mono-src (monolithic Product Catalog Service) to a complete Microservices architecture:
βββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββ
β β β MICROSERVICES PLATFORM β
β mono-src β β β
β (Monolithic) β βββββββΊ β βββββββββββ βββββββββββ βββββββββββ β
β β β β User β β Product β β Order β β
β β’ User Auth β β β Service β β Service β β Service β β
β β’ Product CRUD β β ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ β
β β’ Single DB β β β β β β
β β β ββββββΌβββββ ββββββΌβββββ ββββββΌβββββ β
βββββββββββββββββββββββ β β DB β β DB β β DB β β
β βββββββββββ βββββββββββ βββββββββββ β
β β
β + API Gateway (Kong) β
β + Message Broker (RabbitMQ) β
β + Cache (Redis) β
β + Observability Stack β
βββββββββββββββββββββββββββββββββββββββββββ
Technology Stackβ
| Component | Technology | Port |
|---|---|---|
| User Service | FastAPI + PostgreSQL | 8001 |
| Product Service | FastAPI + PostgreSQL + Redis | 8002 |
| Order Service | FastAPI + PostgreSQL + RabbitMQ | 8003 |
| Notification Service | FastAPI + RabbitMQ | 8004 |
| API Gateway | Kong | 8000 |
| Cache | Redis | 6379 |
| Message Broker | RabbitMQ | 5672, 15672 |
| Tracing | Jaeger | 16686 |
| Metrics | Prometheus | 9090 |
| Logging | Loki + Promtail | 3100 |
| Visualization | Grafana | 3000 |
Target Architectureβ
βββββββββββββββββββ
β Svelte SPA β
β (Port 5173) β
ββββββββββ¬βββββββββ
β
ββββββββββΌβββββββββ
β Kong Gateway β
β (Port 8000) β
ββββββββββ¬βββββββββ
β
ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ
β β β
βββββββββΌββββββββ ββββββββββΌβββββββββ ββββββββββΌβββββββββ
β User Service βββββββββββ Product Service β β Order Service β
β (Port 8001) β Token β (Port 8002) β β (Port 8003) β
β β Verify β β β β
β βββββββββββ β β βββββββββββ β β βββββββββββ β
β βPostgreSQLβ β β βPostgreSQLβ β β βPostgreSQLβ β
β β user_db β β β βproduct_dbβ β β β order_db β β
β βββββββββββ β β βββββββββββ β β βββββββββββ β
βββββββββββββββββ β β β β
β βββββββββββ β β β β
β β Redis β β β β β
β β Cache β β β βΌ β
β βββββββββββ β β ββββββββββββ β
βββββββββββββββββββ β β RabbitMQ β β
β β Publisherβ β
β ββββββ¬ββββββ β
βββββββββΌββββββββββ
β
βββββββββΌββββββββββ
β Notification β
β Service β
β (Port 8004) β
β β
β βββββββββββββ β
β β RabbitMQ β β
β β Consumer β β
β βββββββββββββ β
βββββββββββββββββββ
Assignment 01: User Service Extractionβ
Unit 1 - Microservices Fundamentals & Refactoringβ
π― Learning Objectivesβ
- Understand Bounded Context and Database per Service concepts
- Apply the Strangler Fig Pattern to migrate services
- Set up an independent microservice with FastAPI
π Business Requirementsβ
Scenarioβ
The company has decided to transition from a monolithic to a microservices architecture to:
- Scale components independently
- Deploy features without affecting the entire system
- Allow teams to work in parallel
User Service is selected first because:
- It has a clear Bounded Context (Authentication domain)
- It has few dependencies on other domains
- It is a critical component - needs stability and independent scaling
β Required Tasksβ
Task 1.1: Project Structure Setup (15 points)β
Requirements:
Create the directory structure for User Service following clean architecture pattern:
micro-src/
βββ server/
βββ user-service/
βββ app/
β βββ __init__.py
β βββ main.py # FastAPI app entry
β βββ api/ # API endpoints layer
β βββ config/ # Configuration management
β βββ database/ # Database connection
β βββ models/ # SQLAlchemy models
β βββ repositories/ # Data access layer
β βββ schemas/ # Pydantic schemas
β βββ services/ # Business logic layer
β βββ utils/ # Utilities (security, etc.)
βββ alembic/
βββ tests/
βββ Dockerfile
βββ requirements.txt
βββ alembic.ini
βββ start.sh
Acceptance Criteria:
- Correct directory structure with all layers
- All
__init__.pyfiles exist - Code from mono-src migrated and refactored
Task 1.2: Database per Service (20 points)β
Business Logic:
User Service requires a separate, completely isolated database:
- Do not share schema with other services
- Independent DB scaling
- Independent migration
Technical Requirements:
| Setting | Value |
|---|---|
| Database | PostgreSQL 15 |
| DB Name | user_service_db |
| Port (external) | 5433 |
| Port (internal) | 5432 |
Requirements:
- Create Docker Compose configuration for PostgreSQL container
- Configure environment variables for database credentials
- Set up volume for data persistence
- Implement healthcheck for container readiness
Acceptance Criteria:
- Database container runs successfully
- Connection from service to DB works
- Healthcheck passes
- Data persists across container restarts
Task 1.3: User Model & Migrations (15 points)β
Business Logic:
Migrate the User model from mono-src, ensuring:
- Preserve schema structure
- Alembic migrations work
- Auto-migration when the container starts
Model Definition:
| Column | Type | Constraints |
|---|---|---|
| id | Integer | PK, auto-increment |
| username | String(50) | Unique, Not Null, Indexed |
| hashed_password | String(255) | Not Null |
| is_active | Boolean | Default True |
| created_at | DateTime | Server default now() |
| updated_at | DateTime | Auto-update |
Requirements:
- Initialize Alembic for migrations
- Create initial migration script
- Implement
start.shthat runs migrations before starting the service
Acceptance Criteria:
- Alembic initialized
- Initial migration generated
-
start.shruns migrations automatically
Task 1.4: Authentication Endpoints (25 points)β
Business Logic:
Migrate and enhance authentication endpoints from mono-src:
| Endpoint | Method | Description |
|---|---|---|
/register | POST | User registration |
/login | POST | OAuth2 Password Flow |
/validate-token | POST | NEW - Token validation for other services |
/health | GET | Health check |
Token Validation Endpoint (Important):
This is a NEW endpoint, not present in mono-src. Other services (Product, Order) will call this endpoint to validate JWT tokens instead of decoding the token directly.
Request/Response Format:
- Request: JSON body with
tokenfield containing the JWT - Response (Valid):
{ "valid": true, "user_id": <id>, "username": "<name>", "message": "Token is valid" } - Response (Invalid):
{ "valid": false, "user_id": null, "username": null, "message": "Token is invalid or expired" }
Why not share the JWT secret?
- Security: Each service does not need to know the secret key
- Centralized auth: User Service is the Single Source of Truth
- Rotation: Keys can be rotated without updating other services
Acceptance Criteria:
- POST /register creates user successfully
- POST /login returns JWT token
- POST /validate-token validates and returns user info
- GET /health returns status
Task 1.5: Dockerization (15 points)β
Business Logic:
The Service needs to be containerized for easy deployment:
- Multi-stage build (optional) to reduce image size
- Non-root user for security
- Auto-migration on startup
Requirements:
- Create Dockerfile with Python 3.11 base image
- Install dependencies efficiently (layer caching)
- Create non-root user for security
- Configure healthcheck
- Use start.sh as entrypoint
Acceptance Criteria:
- Docker build successful
- Container starts and is healthy
- Migrations run automatically
- API accessible at port 8001
π Bonus Tasksβ
Bonus 1.1: User Events Publishing (15 points)β
Implement event publishing when a user registers. Publish a user.created event to RabbitMQ containing user_id, username, and created_at.
Bonus 1.2: Password Policy (10 points)β
Implement password policy validation: min 8 chars, 1 uppercase, 1 lowercase, 1 digit, 1 special char. Return specific error messages for each failed rule.
Bonus 1.3: Rate Limiting (10 points)β
Implement rate limiting for the login endpoint: max 5 attempts per minute per IP. Use in-memory storage or Redis.
π Rubric - Assignment 01β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Project Structure (15pts) | Perfect structure, all files | Minor issues | Basic structure | Incorrect structure |
| Database Setup (20pts) | Isolated DB, healthcheck, volumes | Works, minor config issues | Basic setup | Cannot connect |
| Model & Migrations (15pts) | Alembic works, auto-migrate | Works manually | Partial | Not working |
| Auth Endpoints (25pts) | All 4 endpoints, validate-token works | Missing 1 endpoint | 2 endpoints work | Most broken |
| Dockerization (15pts) | Multi-stage, non-root, healthcheck | Basic Dockerfile works | Container runs | Build fails |
| Code Quality (10pts) | Clean, documented, type hints | Good code | Acceptable | Poor quality |
Total: 100 points | Bonus: 35 points
π Assignment 02: Product Service & API Gatewayβ
Unit 2 - API Gateway (Kong)β
π― Learning Objectivesβ
- Extract Product Service into an independent microservice
- Implement inter-service authentication
- Setup and configure Kong API Gateway
- Understand routing and rate limiting concepts
π Business Requirementsβ
Scenarioβ
After the User Service is stable, the team continues to migrate the Product Service. At the same time, an API Gateway is needed to:
- Provide a single entry point for all API calls
- Centralize routing and security
- Implement rate limiting to protect services
- Handle logging and monitoring
β Required Tasksβ
Task 2.1: Product Service Extraction (25 points)β
Business Logic:
Migrate the Product domain from mono-src into an independent service. Product Service:
- Has a separate database (product_service_db)
- Does NOT decode JWT tokens directly
- Calls User Service to validate tokens
Project Structure:
product-service/
βββ app/
β βββ main.py
β βββ api/
β β βββ products.py # CRUD endpoints
β β βββ deps.py # Auth dependency
β βββ config/
β βββ database/
β βββ models/
β βββ repositories/
β βββ schemas/
β βββ services/
β βββ utils/
β βββ auth_client.py # HTTP client to User Service
βββ alembic/
βββ Dockerfile
βββ requirements.txt
Acceptance Criteria:
- Service runs on port 8002
- Separate database (product_service_db, port 5434)
- CRUD endpoints functional
Task 2.2: Inter-Service Authentication (25 points)β
Business Logic:
Product Service needs to authenticate the user but does NOT have access to the JWT secret.
Authentication Flow:
- Client sends request with
Authorization: Bearer <token>to Product Service - Product Service extracts token and calls User Service's
/validate-tokenendpoint - User Service validates token and returns user info or error
- Product Service allows/denies request based on validation result
Requirements:
- Create
AuthClientclass to communicate with User Service - Implement
get_current_userdependency for protected routes - Return 401 Unauthorized when token is invalid/missing
- Make user info available in route handlers
Acceptance Criteria:
- Auth client calls User Service successfully
- Protected endpoints require valid token
- 401 returned when token is invalid/missing
- User info available in route handlers
Task 2.3: Kong API Gateway Setup (30 points)β
Business Logic:
Kong Gateway provides:
- Routing: Direct requests to correct service
- Rate Limiting: Protect services from abuse
- Logging: Centralized access logs
- Authentication (optional): Can add JWT plugin
Requirements:
- Set up Kong with PostgreSQL database using Docker Compose
- Run Kong migrations
- Configure Kong services and routes via Admin API:
- Register User Service:
/api/users/*βuser-service:8001 - Register Product Service:
/api/products/*βproduct-service:8002
- Register User Service:
Routing Table:
| Client Request | Kong Route | Upstream |
|---|---|---|
| POST /api/users/register | /api/users/* | user-service:8001/register |
| POST /api/users/login | /api/users/* | user-service:8001/login |
| GET /api/products | /api/products/* | product-service:8002/products |
| POST /api/products | /api/products/* | product-service:8002/products |
Acceptance Criteria:
- Kong container running healthy
- User Service accessible via Kong
- Product Service accessible via Kong
- Direct service access still works (for internal calls)
Task 2.4: Rate Limiting Plugin (10 points)β
Business Logic:
Protect API from abuse with rate limiting:
- Login endpoint: 5 requests/minute (prevent brute force)
- Product listing: 100 requests/minute
- Product creation: 20 requests/minute
Requirements:
- Configure global rate limiting plugin
- Configure service-specific rate limiting
- Verify rate limit headers in responses
Acceptance Criteria:
- Rate limiting plugin enabled
- Exceeded requests return 429 Too Many Requests
- Headers show rate limit info (X-RateLimit-*)
π Bonus Tasksβ
Bonus 2.1: Kong Declarative Config (15 points)β
Create a kong.yml declarative config file instead of using Admin API calls. Mount it to the container with KONG_DECLARATIVE_CONFIG.
Bonus 2.2: JWT Plugin (15 points)β
Configure Kong JWT plugin to validate tokens at the gateway level. Requires registering consumer and credentials.
Bonus 2.3: Request/Response Transformation (10 points)β
Add a transformation plugin to add custom headers (X-Request-ID, X-Service-Name) into responses.
π Rubric - Assignment 02β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Product Service (25pts) | Complete CRUD, isolated DB | Missing 1 feature | Basic CRUD works | Service broken |
| Inter-Service Auth (25pts) | Auth client works, proper errors | Works, error handling weak | Basic validation | Not implemented |
| Kong Setup (30pts) | Full routing, both services | One service works | Kong runs, partial routing | Kong not working |
| Rate Limiting (10pts) | Multiple limits configured | Basic limit works | Plugin enabled | Not configured |
| Code Quality (10pts) | Clean, async, documented | Good code | Acceptable | Poor quality |
Total: 100 points | Bonus: 40 points
π Assignment 03: Async Communication (RabbitMQ)β
Unit 3 - Async Communicationβ
π― Learning Objectivesβ
- Understand the difference between Sync vs Async communication
- Setup RabbitMQ with Exchange, Queue, Binding
- Implement Producer/Consumer pattern with aio-pika
- Handle message acknowledgment and error cases
π Business Requirementsβ
Scenarioβ
When a user registers, the system needs to send a welcome email. If the email API is called synchronously:
- User must wait for email sending to complete (slow response)
- If the email service is down β registration fails (not acceptable)
Solution: Async communication via message queue.
ββββββββββββββββ 1.Register ββββββββββββββββ
β Client β βββββββββββββΊ β User Service β
ββββββββββββββββ β β
β² β 2. Create β
β β User β
β 3. Return β β
β 201 Created β 4. Publish β
β (immediate) β Event β
βββββββββββββββββββββββββ΄βββββββ¬ββββββββ
β
ββββββββΌββββββββ
β RabbitMQ β
β user.createdβ
ββββββββ¬ββββββββ
β
ββββββββΌββββββββ
β Notification β
β Service β
β β
β 5. Send Emailβ
β (async) β
ββββββββββββββββ
β Required Tasksβ
Task 3.1: RabbitMQ Setup (15 points)β
Requirements:
- Configure RabbitMQ container with management UI
- Set up healthcheck
- Configure data persistence with volumes
Concepts to Understand:
| Concept | Description |
|---|---|
| Exchange | Router that receives messages and routes them to queues |
| Queue | Buffer that stores messages waiting to be consumed |
| Binding | Rule connecting exchange to queue |
| Routing Key | Pattern to route message to correct queue |
Exchange Types:
| Type | Behavior |
|---|---|
| direct | Route by exact routing key match |
| topic | Route by pattern matching (*.created, order.#) |
| fanout | Broadcast to all bound queues |
| headers | Route based on headers |
Acceptance Criteria:
- RabbitMQ container healthy
- Management UI accessible at :15672
- Can create exchange/queue via UI
Task 3.2: Event Publisher - User Service (25 points)β
Business Logic:
After user registers successfully, publish event to RabbitMQ.
Event Structure:
{
"event": "user.created",
"timestamp": "2025-12-24T10:00:00Z",
"data": {
"user_id": 1,
"username": "john_doe",
"email": "john@example.com",
"created_at": "2025-12-24T10:00:00Z"
}
}
Requirements:
- Create
RabbitMQPublisherclass with async connection handling - Declare
user_eventsexchange (topic, durable) - Publish event after successful user registration
- Use persistent delivery mode for messages
Acceptance Criteria:
- Exchange
user_eventscreated (durable) - Event published when user registers
- Message visible in RabbitMQ Management UI
- Registration is still fast (async publish)
Task 3.3: Event Consumer - Notification Service (30 points)β
Business Logic:
Notification Service consumes events and sends notifications:
- Welcome email when user registers
- Order confirmation when order created (future)
Project Structure:
notification-service/
βββ app/
β βββ main.py
β βββ config/
β βββ utils/
β βββ rabbitmq.py # Consumer
β βββ notifications.py # Email/SMS handlers
βββ Dockerfile
βββ requirements.txt
Requirements:
- Create
RabbitMQConsumerclass with proper connection handling - Set QoS (prefetch_count) for controlled consumption
- Declare queue
user_notificationsand bind to exchange - Implement message handling with proper acknowledgment
- Start consumer as background task on application startup
Acceptance Criteria:
- Queue
user_notificationscreated - Queue bound to exchange with routing key
- Consumer receives messages
- Message acknowledged after processing
- Failed messages handled (DLQ or retry)
Task 3.4: Error Handling & Reliability (20 points)β
Business Logic:
Message queue needs to be reliable:
- Messages must not be lost if consumer crashes
- Failed messages need to be retried or moved to DLQ
- Consumer crash should not block other messages
Reliability Patterns to Implement:
| Pattern | Description |
|---|---|
| Persistent Messages | Messages saved to disk |
| Manual Acknowledgment | Ack after processing, nack on failure |
| Dead Letter Queue | Failed messages moved to separate queue |
| Automatic Reconnection | Consumer reconnects after connection loss |
Acceptance Criteria:
- Messages persistent (survive broker restart)
- Failed messages requeued or sent to DLQ
- Consumer reconnects after connection loss
- No message loss in failure scenarios
π Bonus Tasksβ
Bonus 3.1: Retry with Exponential Backoff (15 points)β
Implement retry mechanism with exponential backoff: 1s β 2s β 4s β 8s β DLQ. Track retry count in message headers.
Bonus 3.2: Multiple Consumers (10 points)β
Scale consumer horizontally by running multiple instances. Test with 3 consumer instances using competing consumers pattern.
Bonus 3.3: Event Schema Registry (10 points)β
Create shared event schemas package. Define JSON Schema for each event type. Validate messages against schema before publish/consume.
π Rubric - Assignment 03β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| RabbitMQ Setup (15pts) | Healthy, UI works, concepts clear | Works, minor issues | Basic setup | Not running |
| Publisher (25pts) | Events published, persistent, async | Works, missing persistence | Basic publish | Not implemented |
| Consumer (30pts) | Consumes, processes, acknowledges | Works, ack issues | Receives messages | Not working |
| Error Handling (20pts) | DLQ, retry, reconnection | Partial error handling | Basic try/catch | No error handling |
| Code Quality (10pts) | Clean async code, documented | Good code | Acceptable | Poor quality |
Total: 100 points | Bonus: 35 points
π Assignment 04: SAGA Pattern - Order Serviceβ
Unit 4 & 5 - SAGA Pattern (Happy Path & Failure Path)β
π― Learning Objectivesβ
- Understand Distributed Transactions issues (ACID vs BASE)
- Implement SAGA Pattern with Choreography
- Handle Compensating Transactions on failure
- Build Order Service with multi-service coordination
π Business Requirementsβ
Scenarioβ
Order creation involves multiple services:
- User Service: Verify user exists and authenticated
- Product Service: Check stock availability, deduct stock
- Order Service: Create order record
- Notification Service: Send order confirmation
Problem: Distributed Transaction
In a monolith, database transactions ensure atomicity. In microservices, each service has its own DB β Cannot use single transaction.
Solution: SAGA Pattern
SAGA is a sequence of local transactions, where each transaction updates a service and publishes an event to trigger the next transaction.
Happy Path Flow:
Order Service β (order.created) β Product Service β (stock.reserved) β
Order Service β (order.confirmed) β Notification Service β Send Email
Failure Path (Compensating Transaction):
Order Service β (order.created) β Product Service β Stock INSUFFICIENT! β
(stock.failed) β Order Service β CANCEL Order β (order.cancelled)
β Required Tasksβ
Task 4.1: Order Service Setup (20 points)β
Project Structure:
order-service/
βββ app/
β βββ main.py
β βββ api/
β β βββ orders.py
β β βββ deps.py
β βββ config/
β βββ database/
β βββ models/
β β βββ order.py
β β βββ order_item.py
β βββ repositories/
β βββ schemas/
β βββ services/
β βββ utils/
β βββ auth_client.py # Call User Service
β βββ product_client.py # Call Product Service
β βββ rabbitmq.py # Event publisher
βββ alembic/
βββ Dockerfile
βββ requirements.txt
Order Model:
| Column | Type | Description |
|---|---|---|
| id | Integer | PK |
| user_id | Integer | User who placed order |
| status | Enum | PENDING, CONFIRMED, CANCELLED, SHIPPED, DELIVERED |
| total_amount | Decimal | Total order value |
| created_at | DateTime | Order creation time |
| updated_at | DateTime | Last update time |
OrderItem Model:
| Column | Type | Description |
|---|---|---|
| id | Integer | PK |
| order_id | Integer | FK to Order |
| product_id | Integer | Product ID |
| product_name | String | Snapshot of product name |
| quantity | Integer | Quantity ordered |
| unit_price | Decimal | Price at order time |
Why snapshot product data? Product name/price can change, but order needs to preserve information at the time of ordering.
Acceptance Criteria:
- Order Service runs on port 8003
- Order and OrderItem models created
- Migrations work
Task 4.2: Order Creation API (25 points)β
Business Logic:
Create order endpoint needs to:
- Validate user (via User Service)
- Validate products exist (via Product Service)
- Create order with status PENDING
- Publish
order.createdevent - Return order (do not wait for stock reservation)
API Endpoint:
POST /orders
Authorization: Bearer <token>
Content-Type: application/json
Request Body:
{
"items": [
{ "product_id": 1, "quantity": 2 },
{ "product_id": 3, "quantity": 1 }
]
}
Response (201 Created):
{
"id": 1,
"user_id": 5,
"status": "PENDING",
"total_amount": 299.97,
"items": [...],
"created_at": "2025-12-24T10:00:00Z"
}
Acceptance Criteria:
- Order created with status PENDING
- Products fetched from Product Service
- Total calculated correctly
- Event published to RabbitMQ
- Response immediate (not waiting for stock)
Task 4.3: Stock Reservation - Product Service (25 points)β
Business Logic:
Product Service consumes order.created event and reserves stock.
Requirements:
- Add RabbitMQ consumer to Product Service
- Handle
order.createdevent:- Extract order_id and items from event
- Check stock availability for ALL items first
- If all available: deduct stock, publish
stock.reserved - If any insufficient: publish
stock.failedwith reason
- Invalidate product cache after stock changes
Events:
| Event | Routing Key | When |
|---|---|---|
| stock.reserved | stock.reserved | All items reserved successfully |
| stock.failed | stock.failed | Insufficient stock |
Acceptance Criteria:
- Product Service consumes order.created
- Stock deducted when sufficient
- stock.reserved event published on success
- stock.failed event published on failure
- Cache invalidated after stock change
Task 4.4: Order Status Update & Compensation (20 points)β
Business Logic:
Order Service consumes stock events to update order status.
Requirements:
- Handle
stock.reservedevent β Update order to CONFIRMED, publishorder.confirmed - Handle
stock.failedevent β Update order to CANCELLED, record reason, publishorder.cancelled
Order Status Flow:
PENDING βββββββΊ CONFIRMED βββββββΊ SHIPPED βββββββΊ DELIVERED
β
ββββββββββββΊ CANCELLED (compensation)
Acceptance Criteria:
- Order updated to CONFIRMED on success
- Order updated to CANCELLED on failure
- Cancellation reason recorded
- Appropriate events published
π Bonus Tasksβ
Bonus 4.1: Orchestration Pattern (20 points)β
Implement SAGA Orchestrator service instead of Choreography. Orchestrator coordinates steps and handles rollbacks centrally.
Bonus 4.2: Partial Failure Handling (15 points)β
Handle case: Order has 3 items, 2 items have stock, 1 item out of stock. Implement configurable behavior (cancel all vs partial fulfillment).
Bonus 4.3: Order Status WebSocket (10 points)β
Implement WebSocket endpoint /orders/{id}/status for real-time status updates.
π Rubric - Assignment 04β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Order Service Setup (20pts) | Complete with items model | Basic order model | Partial | Not working |
| Order Creation (25pts) | Full validation, event published | Works, minor issues | Basic creation | Broken |
| Stock Reservation (25pts) | Reserve + events for both paths | Success path only | Basic consumer | Not implemented |
| Compensation (20pts) | Full compensation, status flow | Basic cancellation | Partial | No compensation |
| Code Quality (10pts) | Clean, documented, proper async | Good | Acceptable | Poor |
Total: 100 points | Bonus: 45 points
π Assignment 05: Performance - Redis Cachingβ
Unit 6 - Performance Patterns (Redis)β
π― Learning Objectivesβ
- Understand caching strategies (Cache-aside, Read-through, Write-through)
- Implement Cache-aside pattern with Redis
- Handle Cache Invalidation correctly
- Measure performance improvement
π Business Requirementsβ
Scenarioβ
Product Service receives many read requests for product details:
- 80% requests are GET operations
- Same products are queried multiple times
- Database queries take ~50-100ms
Problem: Database bottleneck with high traffic.
Solution: Redis caching to:
- Reduce DB load
- Improve response time (<10ms from cache)
- Handle traffic spikes
β Required Tasksβ
Task 5.1: Redis Setup (15 points)β
Requirements:
- Configure Redis container with Alpine image
- Enable data persistence (AOF)
- Set memory limit and eviction policy (LRU)
- Configure healthcheck
Configuration Options:
| Option | Value | Purpose |
|---|---|---|
appendonly yes | Enable AOF | Data persistence |
maxmemory 256mb | Memory limit | Prevent OOM |
maxmemory-policy allkeys-lru | Eviction policy | LRU when memory full |
Acceptance Criteria:
- Redis container healthy
- redis-cli ping responds PONG
- Persistence enabled
Task 5.2: Cache Manager Implementation (25 points)β
Business Logic:
Create CacheManager class to handle all cache operations.
Cache Key Strategy:
product:{product_id} # Single product
products:list:{skip}:{limit} # Product list (paginated)
products:search:{query} # Search results
Requirements:
- Create
CacheManagerclass withget,set,delete,delete_patternmethods - Implement error handling (cache failures should not crash the application)
- Use JSON serialization for complex objects
- Make TTL configurable with default from settings
- Implement healthcheck method
Acceptance Criteria:
- CacheManager with get/set/delete methods
- Error handling does not crash application
- TTL configurable
- Pattern-based deletion
Task 5.3: Cache-Aside Pattern for Get Product (30 points)β
Business Logic:
Cache-Aside (Lazy Loading) Pattern:
- Check cache first
- If HIT β return cached data
- If MISS β query DB β store in cache β return
Requirements:
- Implement cache-aside pattern in ProductService.get_product()
- Add logging for cache hit/miss
- Configure TTL (default 300 seconds)
- Serialize/deserialize product data correctly
Acceptance Criteria:
- First request queries DB and caches data
- Subsequent requests hit cache
- Response time <10ms for cache hits
- Cache expires after TTL
Task 5.4: Cache Invalidation (20 points)β
Business Logic:
Cache must be invalidated when data changes:
- Product updated β delete
product:{id} - Product deleted β delete
product:{id} - Stock changed β delete
product:{id}
Invalidation Strategies:
| Strategy | When | Implementation |
|---|---|---|
| Write-invalidate | Update/Delete | Delete cache key |
| TTL expiration | Auto | Redis handles |
| Pattern invalidation | Bulk updates | Delete matching keys |
Acceptance Criteria:
- Cache invalidated on update
- Cache invalidated on delete
- Cache invalidated on stock change
- List caches also invalidated
π Bonus Tasksβ
Bonus 5.1: User Profile Caching (15 points)β
Apply caching for User Service's "Get User Profile" API. Track cache hit rate metrics.
Bonus 5.2: Cache Warming (10 points)β
On service startup, pre-populate cache with frequently accessed products (top 100 by views).
Bonus 5.3: Distributed Locking (15 points)β
Implement distributed lock with Redis to prevent "thundering herd" on cache miss. Use Redis SETNX for locking.
π Rubric - Assignment 05β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Redis Setup (15pts) | Full config, persistence, healthcheck | Works, basic config | Container runs | Not running |
| Cache Manager (25pts) | All methods, error handling, patterns | Basic get/set/delete | Partial implementation | Not working |
| Cache-Aside (30pts) | Full pattern, logging, metrics | Works correctly | Basic caching | Broken |
| Invalidation (20pts) | All cases handled, patterns | Most cases | Basic invalidation | Missing |
| Performance (10pts) | Measured improvement, <10ms | Improved response | Some improvement | No change |
Total: 100 points | Bonus: 40 points
π Assignment 06: Observability - Tracing (Jaeger/OTel)β
Unit 6 - Observability (Tracing)β
π― Learning Objectivesβ
- Understand concepts: Trace, Span, Context Propagation
- Setup OpenTelemetry instrumentation
- Integrate Jaeger for distributed tracing
- Debug cross-service requests
π Business Requirementsβ
Scenarioβ
When order creation fails, we need to trace the request across services:
- How long does it take in each service?
- Which service failed?
- Which database query was slow?
Without tracing: Check logs of each service, difficult to correlate.
With tracing: Single view of the entire request journey.
β Required Tasksβ
Task 6.1: Jaeger Setup (15 points)β
Requirements:
- Configure Jaeger all-in-one container
- Enable OTLP endpoint
- Expose UI port (16686)
Key Concepts:
| Concept | Description |
|---|---|
| Trace | End-to-end journey of a request |
| Span | Single operation in a trace (e.g., DB query, HTTP call) |
| Context | Metadata propagated across services (trace ID, span ID) |
| Instrumentation | Code that creates and manages spans |
Acceptance Criteria:
- Jaeger UI accessible at :16686
- OTLP endpoint available at :4317
Task 6.2: OpenTelemetry Setup (25 points)β
Dependencies Required:
- opentelemetry-api
- opentelemetry-sdk
- opentelemetry-instrumentation-fastapi
- opentelemetry-instrumentation-sqlalchemy
- opentelemetry-instrumentation-httpx
- opentelemetry-instrumentation-redis
- opentelemetry-exporter-otlp
Requirements:
- Create
setup_tracing()function for each service - Configure Resource with service identity (name, version, environment)
- Create TracerProvider with OTLP exporter
- Add BatchSpanProcessor for performance
- Auto-instrument: FastAPI, SQLAlchemy, HTTPX, Redis
Required Instrumentations per Service:
| Service | FastAPI | SQLAlchemy | HTTPX | Redis | RabbitMQ |
|---|---|---|---|---|---|
| User | β | β | - | - | Manual |
| Product | β | β | β | β | - |
| Order | β | β | β | - | Manual |
| Notification | β | - | - | - | Manual |
Acceptance Criteria:
- Tracing configured in all services
- Auto-instrumentation for FastAPI, SQLAlchemy, HTTPX, Redis
- Spans exported to Jaeger
Task 6.3: Instrument All Services (30 points)β
Requirements:
- Apply tracing setup to all 4 services
- Create manual spans for RabbitMQ message handlers
- Include relevant attributes (order_id, user_id, etc.)
- Record exceptions in spans
Acceptance Criteria:
- User Service traced
- Product Service traced (including Redis)
- Order Service traced (including HTTPX calls)
- Manual spans for RabbitMQ handlers
Task 6.4: Trace Analysis (20 points)β
Test Scenarios:
- Happy Path: Create order successful - trace shows full flow
- Failure Path: Insufficient stock - trace shows error span
- Cache Hit vs Miss: Cache HIT shows short span, MISS shows DB span
Jaeger UI Features to Use:
| Feature | Usage |
|---|---|
| Service dropdown | Filter by service |
| Operation dropdown | Filter by endpoint |
| Tags search | Find by order_id, user_id |
| Compare traces | Compare slow vs fast |
| Dependencies | Service dependency graph |
Acceptance Criteria:
- Can find traces by service
- Can filter by operation
- Can see full trace across services
- Can identify slow spans
π Bonus Tasksβ
Bonus 6.1: Custom Spans & Attributes (10 points)β
Add custom spans for business-critical operations with custom attributes.
Bonus 6.2: Trace Context in Messages (15 points)β
Propagate trace context via RabbitMQ messages using traceparent header.
Bonus 6.3: Sampling Strategy (10 points)β
Configure trace sampling (probabilistic 10% or rate limiting 100 traces/sec).
π Rubric - Assignment 06β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Jaeger Setup (15pts) | UI works, OTLP enabled | Basic setup | Container runs | Not running |
| OTel Setup (25pts) | All instrumentations | Missing 1-2 | Basic FastAPI only | Not working |
| All Services (30pts) | All 4 services traced | 3 services | 2 services | 1 or none |
| Trace Analysis (20pts) | Full analysis, can debug | Basic viewing | Can find traces | Cannot use UI |
| Code Quality (10pts) | Clean, configurable | Good | Acceptable | Poor |
Total: 100 points | Bonus: 35 points
π Assignment 07: Observability - Logging (Loki)β
Unit 7 - Observability (Logging)β
π― Learning Objectivesβ
- Understand centralized logging concepts
- Setup Loki + Promtail for log aggregation
- Implement structured logging
- Query and analyze logs effectively
π Business Requirementsβ
Scenarioβ
With multiple services, logs are scattered:
- User Service logs β container A
- Product Service logs β container B
- Order Service logs β container C
Problem: Difficult to correlate logs when debugging.
Solution: Centralized logging with Loki.
- All logs β Loki
- Query from Grafana
- Correlate with trace_id
β Required Tasksβ
Task 7.1: Loki + Promtail Setup (20 points)β
Requirements:
- Configure Loki with filesystem storage
- Configure Promtail to collect Docker container logs
- Set up Docker Compose for both services
- Add service labels for filtering
Acceptance Criteria:
- Loki running at :3100
- Promtail collecting Docker logs
- Logs visible in Grafana
Task 7.2: Structured Logging (25 points)β
Business Logic:
JSON structured logs for easy parsing and querying.
Log Format:
{
"timestamp": "2025-12-24T10:00:00.000Z",
"level": "INFO",
"service": "order-service",
"trace_id": "abc123...",
"span_id": "def456...",
"message": "Order created successfully",
"order_id": 1,
"user_id": 5,
"total_amount": 299.97
}
Requirements:
- Create custom JSON formatter with trace context
- Configure logging to stdout
- Support extra fields in log messages
- Reduce noise from uvicorn, httpx
Acceptance Criteria:
- Logs in JSON format
- trace_id included (for correlation)
- Custom fields supported
- Log levels appropriate
Task 7.3: Log Aggregation Verification (25 points)β
Test Scenarios:
- All Services Logging: Start all services, make API requests, verify logs appear in Loki
- Cross-Service Correlation: Create order, find logs by trace_id across services
- Error Logging: Trigger error, search for ERROR level logs, verify stack trace
LogQL Queries to Implement:
| Query Purpose | Description |
|---|---|
| All logs from a service | Filter by container name |
| Error logs only | Filter by level |
| Filter by trace_id | Correlate across services |
| Search for specific order | Filter by custom field |
| Rate of errors | Calculate error rate over time |
Acceptance Criteria:
- Logs from all services visible
- Can filter by service
- Can search by trace_id
- Can search by custom fields
Task 7.4: Log-based Alerting (20 points)β
Requirements:
- Create Grafana alert rule for high error rate
- Configure alert condition (e.g., >10 errors in 5 minutes)
- Test alert firing and resolution
Acceptance Criteria:
- Alert rule created in Grafana
- Alert fires on error spike (test)
- Alert resolves when errors decrease
π Bonus Tasksβ
Bonus 7.1: ELK Stack Alternative (20 points)β
Setup ELK Stack (Elasticsearch, Logstash, Kibana) instead of Loki. Create Kibana dashboard.
Bonus 7.2: Log Retention Policy (10 points)β
Configure log retention: keep 7 days detailed, 30 days aggregated.
Bonus 7.3: Audit Logging (10 points)β
Separate audit logs for security events (login, permission changes). Never delete.
π Rubric - Assignment 07β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Loki Setup (20pts) | Full config, Promtail works | Basic setup | Container runs | Not running |
| Structured Logging (25pts) | JSON, trace_id, custom fields | JSON, missing trace_id | Basic JSON | Unstructured |
| Aggregation (25pts) | All services, can query | Most services | Some logs visible | Cannot query |
| Alerting (20pts) | Alert works, tested | Alert configured | Partial | No alerting |
| Code Quality (10pts) | Clean, reusable | Good | Acceptable | Poor |
Total: 100 points | Bonus: 40 points
π Assignment 08: Observability - Metrics (Prometheus/Grafana)β
Unit 9 - Observability (Metrics)β
π― Learning Objectivesβ
- Understand metrics types: Counter, Gauge, Histogram, Summary
- Setup Prometheus for metrics collection
- Build Grafana dashboards
- Implement custom application metrics
- Setup alerting based on metrics
π Business Requirementsβ
Scenarioβ
The Operations team needs to monitor the system:
- Request rate (requests per second)
- Error rate (% of failed requests)
- Response latency (p50, p90, p99)
- Resource usage (CPU, memory)
- Business metrics (orders/hour, revenue)
Goal: Real-time visibility into system health.
β Required Tasksβ
Task 8.1: Prometheus Setup (20 points)β
Requirements:
- Configure Prometheus with scrape configs for all services
- Set up service discovery for each microservice
- Configure data retention and storage
- Enable web UI
Scrape Targets:
| Job Name | Target |
|---|---|
| prometheus | localhost:9090 |
| user-service | user-service:8001 |
| product-service | product-service:8002 |
| order-service | order-service:8003 |
| redis | redis-exporter:9121 |
| postgres | postgres-exporter:9187 |
Acceptance Criteria:
- Prometheus UI accessible at :9090
- All services discovered in Targets
- Metrics being scraped
Task 8.2: Application Metrics (25 points)β
Metrics Types:
| Type | Use Case | Example |
|---|---|---|
| Counter | Monotonically increasing | Total requests, errors |
| Gauge | Can go up/down | Active connections, queue size |
| Histogram | Distribution of values | Request latency, order value |
| Summary | Similar to histogram | Response size percentiles |
Requirements:
- Setup prometheus-fastapi-instrumentator for each service
- Expose /metrics endpoint (exclude from tracing)
- Add default HTTP metrics (latency, request count)
- Create custom business metrics:
orders_created_total(Counter with status label)order_value_dollars(Histogram with buckets)http_requests_in_progress(Gauge)
Acceptance Criteria:
- /metrics endpoint returns Prometheus format
- Default HTTP metrics (latency, count)
- Custom business metrics recording
Task 8.3: Grafana Dashboards (30 points)β
Requirements:
- Configure Grafana with Prometheus data source
- Set up dashboard provisioning
- Create overview dashboard with key metrics
Required Dashboard Panels:
| Panel | Metric | Type |
|---|---|---|
| Request Rate | sum(rate(http_requests_total[5m])) by (service) | Graph |
| Error Rate | 5xx requests / total requests * 100 | Graph |
| P99 Latency | histogram_quantile(0.99, ...) | Graph |
| Active Requests | http_requests_in_progress | Gauge |
| Orders/Hour | increase(orders_created_total[1h]) | Stat |
Acceptance Criteria:
- Grafana UI accessible at :3000
- Prometheus data source configured
- Overview dashboard with key metrics
- Service-specific dashboard
Task 8.4: Alerting Rules (15 points)β
Required Alert Rules:
| Alert | Condition | Severity |
|---|---|---|
| HighErrorRate | Error rate > 5% for 5min | critical |
| HighLatency | P99 > 2s for 5min | warning |
| ServiceDown | up == 0 for 1min | critical |
| HighMemoryUsage | Memory > 512MB for 5min | warning |
Acceptance Criteria:
- Alert rules loaded in Prometheus
- Alerts fire correctly when triggered
- Alerts visible in Grafana
π Bonus Tasksβ
Bonus 8.1: Custom Grafana Dashboard (15 points)β
Create business dashboard showing: orders per hour, revenue, top products, user signups.
Bonus 8.2: Alertmanager Integration (15 points)β
Setup Alertmanager to route alerts via Slack/Email/Discord.
Bonus 8.3: SLI/SLO Dashboard (15 points)β
Define SLOs (99.9% availability, p99 < 500ms). Create error budget dashboard.
π Rubric - Assignment 08β
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Prometheus Setup (20pts) | Full config, all targets | Most targets | Basic setup | Not working |
| App Metrics (25pts) | Default + custom business | Default metrics | Partial | No metrics |
| Dashboards (30pts) | Multiple dashboards, polished | Overview dashboard | Basic panels | No dashboards |
| Alerting (15pts) | Rules work, tested | Rules configured | Partial | No alerts |
| Code Quality (10pts) | Clean, documented | Good | Acceptable | Poor |
Total: 100 points | Bonus: 45 points
π Final Project: End-to-End Integration & Demoβ
π― Objectivesβ
- Deploy the entire microservices stack
- Demonstrate the E2E user journey
- Verify observability stack
- Present architecture decisions
π Final Project Requirementsβ
Part 1: Complete Deployment (30 points)β
Checklist:
| Component | Requirement |
|---|---|
| User Service | Running, healthy |
| Product Service | Running, cached |
| Order Service | Running, messaging |
| Notification Service | Consuming messages |
| PostgreSQL (3 instances) | Data persisted |
| Redis | Caching working |
| RabbitMQ | Queues active |
| Prometheus | Scraping all services |
| Grafana | Dashboards visible |
| Loki | Logs aggregated |
| Jaeger | Traces visible |
Part 2: E2E User Journey Demo (40 points)β
Demo Steps:
- Register User β User created, 201 response
- Login β Token returned
- Browse Products β Products listed, cache metrics change
- Create Order β Order created, stock reduced
- Notification β Consumer log shows processing
- Tracing β Full trace visible in Jaeger
- Metrics β Dashboard shows request spike
- Logs β Logs searchable by trace_id
Part 3: Failure Scenarios (20 points)β
Test Resilience:
| Scenario | Expected Behavior |
|---|---|
| Kill Product Service | Order Service returns 503, auto-recovers |
| Kill Redis | Product Service fallback to DB (slower) |
| Kill RabbitMQ | Order created, notification delayed |
| Invalid Token | 401 Unauthorized |
| Insufficient Stock | Order fails gracefully |
Part 4: Architecture Presentation (10 points)β
Topics to Present:
- Architecture Overview: Service boundaries, communication patterns, database per service
- Key Design Decisions: Why separate Auth service? Why RabbitMQ for notifications? Why Redis for products?
- Trade-offs: Consistency vs Availability, Complexity vs Simplicity, Performance vs Cost
- Future Improvements: API Gateway (Kong), Service Mesh (Istio), CI/CD Pipeline
π Final Project Rubricβ
| Criteria | Excellent (100%) | Good (80%) | Satisfactory (60%) | Needs Improvement (40%) |
|---|---|---|---|---|
| Deployment (30pts) | All components running | Missing 1-2 | Core services only | Multiple failures |
| E2E Demo (40pts) | Full journey, all verifications | Most steps work | Core flow works | Broken flow |
| Failure Handling (20pts) | Graceful degradation | Most scenarios | Some handling | Crashes |
| Presentation (10pts) | Clear, insightful | Good explanation | Basic | Poor |
Total: 100 points
π Course Summary & Gradingβ
Overall Progress Trackingβ
| Assignment | Topic | Points | Bonus |
|---|---|---|---|
| 01 | User Service Extraction | 100 | 35 |
| 02 | Product Service & API Gateway | 100 | 40 |
| 03 | Async Communication | 100 | 35 |
| 04 | SAGA Pattern - Order Service | 100 | 45 |
| 05 | Performance - Redis Caching | 100 | 40 |
| 06 | Observability - Tracing | 100 | 35 |
| 07 | Observability - Logging | 100 | 40 |
| 08 | Observability - Metrics | 100 | 45 |
| Final | E2E Integration | 100 | - |
| Total | 900 | 315 |
Grading Scaleβ
| Grade | Percentage | Points (of 900) |
|---|---|---|
| A+ | 95-100% | 855-900 |
| A | 90-94% | 810-854 |
| B+ | 85-89% | 765-809 |
| B | 80-84% | 720-764 |
| C+ | 75-79% | 675-719 |
| C | 70-74% | 630-674 |
| D | 60-69% | 540-629 |
| F | < 60% | < 540 |
Bonus Points: Can increase grade (max +10%)
π Additional Resourcesβ
Documentationβ
- FastAPI Documentation
- SQLAlchemy 2.0 Documentation
- RabbitMQ Tutorials
- Redis Documentation
- OpenTelemetry Python
- Prometheus Documentation
- Grafana Documentation
Architecture Patternsβ
Last Updated: 2026-01-13
Version: 1.1.0
Syllabus Reference: Advanced Microservices Architecture
Note: This document provides requirements and descriptions only. Students are expected to research and implement the solutions independently. Refer to the provided resources and course materials for implementation guidance.