Introduction
Service separation is the most important architectural decision when moving to Microservices. Divided too small → complexity explodes. Divided too large → distributed monolith. This article guides a systematic method to properly define service boundaries.

1. Principle of separation
1.1 Single Responsibility for Services
Each service is responsible for a unique business capability:
- User Service → User lifecycle management (register, login, profile)
- Product Service → Product catalog, search, reviews
- Order Service → Order processing, fulfillment, history
1.2 Two main strategies
Decompose by Business Capability:
Based on the business functions the organization provides:
E-Commerce Business Capabilities:
├── Customer Management → User Service
├── Product Management → Product Service
├── Order Management → Order Service
├── Payment Processing → Payment Service
├── Inventory Management → Inventory Service
└── Shipping & Delivery → Shipping Service
Decompose by Subdomain (DDD):
Based on subdomains identified via DDD:
Core Subdomains (competitive advantage):
├── Product Catalog → Product Service (custom-built, best team)
├── Order Processing → Order Service (complex logic)
Supporting Subdomains (necessary but not differentiating):
├── Inventory → Inventory Service
├── Customer Profile → User Service
Generic Subdomains (solved problems):
├── Authentication → Keycloak (off-the-shelf)
├── Payment Gateway → Stripe integration
├── Email → SendGrid/SES
1.3 Correct service boundaries signs
- Service can be developed, deployed, scaled independently
- Changes in service A seldom require changes in service B
- Each service has its own database (no shared tables)
- Teams can work on the service without needing to coordinate with other teams
- Service has cohesive API — closely related endpoints
2. Context Mapping Patterns
Once you have identified Bounded Contexts, you need to define the relationship between them:
2.1 Partnership
The two teams cooperate closely, jointly developing the interface:
Product Team ←→ Search Team
(cùng định nghĩa product schema cho search indexing)
2.2 Customer-Supplier
Upstream (supplier) provides data/API, Downstream (customer) consumes:
Product Service (Supplier) → Order Service (Customer)
(Order Service cần product info nhưng không thay đổi product)
2.3 Anti-Corruption Layer (ACL)
Transformation layer to protect domain model from external/legacy systems:
┌──────────┐ ┌─────┐ ┌──────────────┐
│ Order │ ──► │ ACL │ ──► │ Legacy ERP │
│ Service │ │ │ │ (SOAP/XML) │
└──────────┘ └─────┘ └──────────────┘
ACL convert REST/JSON ↔ SOAP/XML
3. Anti-patterns should be avoided
3.1 Distributed Monolith
❌ Services phụ thuộc chặt chẽ:
Service A → Service B → Service C → Service A (circular!)
Kết quả: phải deploy A, B, C cùng lúc = worse than monolith
3.2 Nano-services
❌ Chia quá nhỏ:
├── ProductNameService
├── ProductPriceService
├── ProductImageService
└── ProductReviewService
✅ Chia hợp lý:
└── ProductService (gom lại thành 1 service)
3.3 Shared Database
❌ Nhiều services dùng chung DB:
Service A ──┐
Service B ──┼──► Shared PostgreSQL (products table)
Service C ──┘
Thay đổi schema → break tất cả services
✅ Database per Service:
Service A → DB_A
Service B → DB_B (replicate data nếu cần)
Service C → DB_C
4. Hands-on: Separating E-Commerce Platform
Applicable to projects throughout the series:
E-Commerce Platform Services:
┌─────────────────────────────────────────┐
│ User Service (Supporting) │
│ - Registration, Login, Profile │
│ - PostgreSQL (users, addresses) │
│ - Team: 2-3 devs │
├─────────────────────────────────────────┤
│ Product Service (Core) │
│ - Catalog, Search, Reviews, Categories │
│ - PostgreSQL + Elasticsearch │
│ - Team: 3-4 devs │
├─────────────────────────────────────────┤
│ Cart Service (Supporting) │
│ - Add/Remove items, Apply coupon │
│ - Redis (fast, ephemeral) │
│ - Team: 2 devs │
├─────────────────────────────────────────┤
│ Order Service (Core) │
│ - Place order, Track, History │
│ - PostgreSQL (orders, order_items) │
│ - Team: 3-4 devs │
├─────────────────────────────────────────┤
│ Payment Service (Generic) │
│ - Stripe/VNPay integration │
│ - PostgreSQL (transactions) │
│ - Team: 2 devs │
└─────────────────────────────────────────┘
Summary
| Principles | Description |
|---|---|
| Divide by Domain | Use DDD Bounded Context, not divided by technical layer |
| Loosely Coupled | Service A changes without needing to deploy Service B |
| High Cohesion | Related functions are located in the same service |
| Own Data | Each service has its own database |
| Right Size | Not too big (monolith), not too small (nano-service) |
Next article: Lesson 5: API Design Masterclass — REST, GraphQL & gRPC