Decomposition Strategies

Strategies for Decomposing a Monolith into Microservices

In this workshop, we analyze decomposition strategies for migrating from a monolith to microservices within a real-world context:
Food Delivery Project or Order Management System consisting of 5 services: Gateway, Kitchen, Order, Payment, Stock.


decompose1

2.1 Decomposition by Business Capabilities

Splitting Based on Business Domains

Core Principle: Decompose services by business capability rather than technical layers.

Identified business capabilities:

  • Order Management: Handle the entire lifecycle of an order
  • Kitchen Operations: Manage food preparation and kitchen processes
  • Payment Processing: Handle payments and financial operations
  • Inventory Management: Manage ingredients and stock
  • API Gateway: Entry point and routing for the entire system

Reasons for choosing business capability split:

  • Each team can focus on a single business domain
  • Easier to scale and maintain
  • Business logic is not fragmented across services

Database Decomposition Strategy

Database-per-Service Pattern:

Each service owns its own MongoDB instance:

  • Gateway Service
  • Order Service
  • Kitchen Service
  • Payment Service
  • Stock Service

Advantages of Database-per-Service:

  • Independent schema evolution
  • Service-specific performance tuning
  • Strong security isolation
  • Independent database scaling

2.2 Decomposition by Data Ownership

Defining Data Ownership

Principle: Each service owns and manages its own data; no shared database tables.

Data Ownership Matrix:

ServiceData OwnedData Accessed (Read-only)
Orderorders, order_items, order_statusesinventory (from Stock), payment_status (from Payment)
Kitchenkitchen_jobs, staff_schedulesorders (from Order), inventory (from Stock)
Paymenttransactions, payment_methodsorders (from Order)
Stockinventory, suppliers, stock_movementsorders (from Order)
Gatewayauth_tokens, rate_limitsAll services (for routing)

Data Access Strategy:

  • Synchronous: gRPC calls for real-time data
  • Asynchronous: RabbitMQ events for data updates
  • Caching: Redis cache for frequently accessed data

Data Consistency Strategy

Eventual Consistency with Event Sourcing:

1. Order Creation Flow:


Order Service → OrderCreated Event → RabbitMQ
↓
Stock Service ← Consume Event → Update Inventory
Payment Service ← Consume Event → Create Payment Record
Kitchen Service ← Consume Event → Create Kitchen Job

2. Payment Processing Flow:


Payment Service → PaymentCompleted Event → RabbitMQ
↓
Order Service ← Consume Event → Update Order Status
Kitchen Service ← Consume Event → Start Cooking Process

3. Inventory Update Flow:


Stock Service → StockUpdated Event → RabbitMQ
↓
Order Service ← Consume Event → Check Availability
Kitchen Service ← Consume Event → Update Cooking Plan

Compensation Pattern for Failure Scenarios:

  • If Stock Service fails → Rollback Order
  • If Payment Service fails → Cancel Kitchen Job
  • If Kitchen Service fails → Refund Payment

2.3 Decomposition by Service Dependencies

Dependency Analysis

Service Dependency Graph:


Gateway (Entry Point)
├── Order Service (Core Business)
│   ├── Stock Service (Inventory Check)
│   ├── Payment Service (Payment Processing)
│   └── Kitchen Service (Order Fulfillment)
├── Kitchen Service
│   ├── Stock Service (Ingredient Check)
│   └── Order Service (Order Details)
├── Payment Service
│   └── Order Service (Order Validation)
└── Stock Service
└── Order Service (Demand Forecasting)

Dependency-based Decomposition Strategy:

Level 1 - Independent Services (Decompose first):

  • Stock Service: Fewest dependencies, can be separated first
  • Payment Service: Only depends on Order Service

Level 2 - Core Business Services:

  • Order Service: Core business logic, multiple dependencies
  • Kitchen Service: Depends on Order and Stock

Level 3 - Gateway Service:

  • Gateway Service: Separated last, once all services are stable

Dependency-based Migration Strategy

Phase 1: Foundation Services

  • Extract Stock Service first (least dependencies)
  • Setup MongoDB, RabbitMQ, Consul
  • Implement basic CRUD operations

Phase 2: Business Services

  • Extract Payment Service (dependency: Order)
  • Extract Kitchen Service (dependencies: Order, Stock)
  • Implement event-driven communication

Phase 3: Core Service

  • Extract Order Service (core business logic)
  • Implement complex workflows
  • Handle cross-service transactions

Phase 4: Gateway Service

  • Extract Gateway Service (depends on all services)
  • Implement routing, authentication, rate limiting

Summary

Decomposition strategies for migrating the Food Delivery project from monolith to microservices:

  1. Business Capability Split: Decompose into 5 clear business domains
  2. Database-per-Service: Each service has its own MongoDB instance
  3. Data Ownership: Each service owns its data independently
  4. Eventual Consistency: Cross-service communication via RabbitMQ events
  5. Dependency-based Migration: Extract services from least dependent to core services

Expected outcomes:

  • Independent, maintainable, and scalable services
  • Data consistency ensured via event-driven architecture
  • Higher team productivity through domain-focused development
  • Improved system resilience with circuit breaker and compensation patterns