Microservices Patterns

Core Patterns

PatternProblem SolvedHow It Works
API GatewayClient talks to many servicesSingle entry point; routes, auth, rate-limit, aggregates
Circuit BreakerCascading failuresOpens after N failures; fast-fails; half-open probe
SagaDistributed transactionsChain of local transactions + compensating transactions
CQRSRead/write contentionSeparate read model from write model
Event SourcingAudit trail, time travelStore events, not state; rebuild state from event log
Outbox PatternDual write (DB + message) atomicityWrite to DB outbox table; relay publishes to broker
Strangler FigMigrating monolith incrementallyRoute new features to new service; retire old code piece by piece
SidecarCross-cutting concerns per podCo-deploy proxy (Envoy/Linkerd) for observability, auth

Circuit Breaker Implementation

// Circuit Breaker states: CLOSED → OPEN → HALF-OPEN → CLOSED class CircuitBreaker { constructor(fn, { threshold = 5, timeout = 60000, halfOpenRequests = 1 } = {}) { this.fn = fn; this.state = 'CLOSED'; this.failureCount = 0; this.threshold = threshold; this.timeout = timeout; this.nextAttempt = null; } async call(...args) { if (this.state === 'OPEN') { if (Date.now() < this.nextAttempt) { throw new Error('Circuit breaker is OPEN'); } this.state = 'HALF-OPEN'; } try { const result = await this.fn(...args); this.onSuccess(); return result; } catch (err) { this.onFailure(); throw err; } } onSuccess() { this.failureCount = 0; this.state = 'CLOSED'; } onFailure() { this.failureCount++; if (this.failureCount >= this.threshold || this.state === 'HALF-OPEN') { this.state = 'OPEN'; this.nextAttempt = Date.now() + this.timeout; } } } // Usage with resilience4j (Java / Spring Boot) @CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback") public PaymentResult processPayment(Order order) { ... } public PaymentResult paymentFallback(Order order, Exception e) { return PaymentResult.queued(order.getId()); // degrade gracefully }

Saga Pattern: Choreography vs Orchestration

// Choreography Saga — services react to events // OrderService emits OrderCreated // PaymentService listens → emits PaymentProcessed or PaymentFailed // InventoryService listens → emits StockReserved or StockFailed // Each service handles compensating events // Example event flow: OrderCreated → PaymentProcessed → StockReserved → OrderConfirmed ↗ PaymentFailed → OrderCancelled ↗ StockFailed → RefundPayment → OrderCancelled // Orchestration Saga — central orchestrator directs steps class OrderSagaOrchestrator { async execute(orderId) { try { await paymentService.charge(orderId); await inventoryService.reserve(orderId); await shippingService.schedule(orderId); await orderService.confirm(orderId); } catch (err) { // Compensate in reverse order await shippingService.cancel(orderId); await inventoryService.release(orderId); await paymentService.refund(orderId); await orderService.cancel(orderId); } } }