Service Per Subdomain Pattern :👈 👉:Asynchronous Messaging Pattern

Service Per Business Capability Pattern

Service Per Business Capability Pattern in Microservices

The Service Per Business Capability pattern is one of the most common ways to design microservices. The idea is simple:

Each microservice is responsible for one complete business capability of the organization.

A business capability is something a business does to deliver value.

Examples:

  • Customer Management
  • Order Processing
  • Billing
  • Inventory Management
  • Shipping
  • Human Resources
  • Payroll

Each capability becomes an independent microservice.

What is a Business Capability?

A business capability represents a specific business function that can operate relatively independently.

For example, in an online shopping company:

Business Capabilities
├── Customer Management
├── Product Catalog
├── Shopping Cart
├── Order Processing
├── Payment Processing
├── Inventory Management
├── Shipping
└── Notification

Each capability has:

  • Business Rules
  • Database
  • APIs
  • UI Components (optional)
  • Independent Team

Therefore:

Customer Management  -> Customer Service
Order Processing     -> Order Service
Payments             -> Payment Service
Inventory            -> Inventory Service
Shipping             -> Shipping Service

Core Principle

Instead of dividing services by technical layers:

❌ Wrong Approach

User API Service
Database Service
Validation Service
Logging Service
Email Service

This creates excessive service communication.

Instead, divide by business responsibility.

✅ Correct Approach

Customer Service
Order Service
Payment Service
Inventory Service

Each service contains everything needed for its business capability.

Real World Example: Amazon-like Application

Imagine an e-commerce system.

Monolithic System

ECommerce Application
├── Customer Module
├── Product Module
├── Cart Module
├── Orders Module
├── Payments Module
├── Inventory Module
└── Shipping Module

Everything is deployed together.

Problems:

  • Huge codebase
  • Difficult deployments
  • Long testing cycles
  • Hard scalability

Service Per Business Capability

The monolith is split into independent services.

                    API Gateway
                         │
        ┌────────────────┼────────────────┐
        │                │                │
        ▼                ▼                ▼
Customer Service   Order Service   Product Service
        ▼                ▼                ▼
   CustomerDB        OrderDB        ProductDB
                         │
              ┌──────────┼──────────┐
              ▼          ▼          ▼
      Inventory Service  Payment Service  Shipping Service
              ▼               ▼                ▼
        InventoryDB      PaymentDB        ShippingDB

Responsibility of Each Service

Customer Service

Handles:

  • Registration
  • Login
  • Customer Profile
  • Address Management

Endpoints:

GET /api/customers/1
POST /api/customers
PUT /api/customers/1

Database:

CustomerDB

Product Service

Handles:

  • Product Catalog
  • Categories
  • Product Details

Endpoints:

GET /api/products
GET /api/products/100

Database:

ProductDB

Order Service

Handles:

  • Create Order
  • Cancel Order
  • Track Order

Endpoints:

POST /api/orders
GET /api/orders/1001

Database:

OrderDB

Payment Service

Handles:

  • Credit Card Payment
  • Refund
  • Transaction History

Endpoints:

POST /api/payments

Database:

PaymentDB

Order Placement Flow

When a customer places an order:

Customer
   │
   ▼
Order Service
   │
   ├── Get Product Details
   │
   ▼
Product Service
   │
   ▼
Inventory Service
   │
   ▼
Payment Service
   │
   ▼
Shipping Service

Every service contributes only to its own capability.

.NET Example

Let's create an Order Service responsible for the Order Processing capability.

Order Entity

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public decimal Amount { get; set; }
    public string Status { get; set; }
    public DateTime CreatedDate { get; set; }
}

DbContext

using Microsoft.EntityFrameworkCore;
public class OrderDbContext : DbContext
{
    public OrderDbContext(DbContextOptions<OrderDbContext> options)
        : base(options)
    {
    }
    public DbSet<Order> Orders { get; set; }
}

Order Service Layer

public class OrderService
{
    private readonly OrderDbContext _context;
    public OrderService(OrderDbContext context)
    {
        _context = context;
    }
    public async Task<Order> CreateOrderAsync(Order order)
    {
        _context.Orders.Add(order);
        await _context.SaveChangesAsync();
        return order;
    }
    public async Task<Order?> GetOrderAsync(int id)
    {
        return await _context.Orders.FindAsync(id);
    }
}

Orders Controller

[ApiController]
[Route("api/orders")]
public class OrdersController : ControllerBase
{
    private readonly OrderService _service;
    public OrdersController(OrderService service)
    {
        _service = service;
    }
    [HttpPost]
    public async Task<IActionResult> Create(Order order)
    {
        var result =
            await _service.CreateOrderAsync(order);
        return Ok(result);
    }
    [HttpGet("{id}")]
    public async Task<IActionResult> Get(int id)
    {
        var order =
            await _service.GetOrderAsync(id);
        if (order == null)
            return NotFound();
        return Ok(order);
    }
}

Each Capability Has Its Own Database

One major principle:

✅ Recommended

Customer Service  --> CustomerDB
Order Service     --> OrderDB
Payment Service   --> PaymentDB

❌ Not Recommended

Customer Service
Order Service
Payment Service
      │
      ▼
   SharedDB

A shared database creates tight coupling between services.

Communication Between Business Capabilities

Synchronous Communication

Using REST APIs.

Order Service calls Customer Service.

public class CustomerClient
{
    private readonly HttpClient _httpClient;
    public CustomerClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
    public async Task<CustomerDto> GetCustomer(int id)
    {
        return await _httpClient
            .GetFromJsonAsync<CustomerDto>
            ($"api/customers/{id}");
    }
}

Asynchronous Communication

Using:

  • RabbitMQ
  • Azure Service Bus
  • Kafka

Order Service publishes:

public class OrderCreatedEvent
{
    public int OrderId { get; set; }
    public decimal Amount { get; set; }
}

Publish:

await _publishEndpoint.Publish(
    new OrderCreatedEvent
    {
        OrderId = 100,
        Amount = 5000
    });

Payment Service consumes:

public class OrderCreatedConsumer :
    IConsumer<OrderCreatedEvent>
{
    public async Task Consume(
       ConsumeContext<OrderCreatedEvent> context)
    {
        var order = context.Message;
        // Process Payment
    }
}

Service Per Business Capability vs Service Per Subdomain

Many developers think they are the same, but there is a small difference.

Service Per Business Capability Service Per Subdomain
Based on business functions Based on Domain-Driven Design subdomains
Simpler approach DDD-oriented approach
Focus on what business does Focus on bounded contexts
Good starting point Better for large enterprise systems

Example

Business Capability View:

Customer Management
Orders
Payments
Shipping

DDD Subdomain View:

Customer Domain
├── Customer Profile
├── Loyalty Program
└── Customer Preferences

A large subdomain may eventually contain multiple business capabilities.

Advantages

1. Independent Development

Team A → Orders
Team B → Payments
Team C → Inventory

Teams work independently.

2. Independent Deployment

Deploy Payment Service without redeploying Order Service.

3. Independent Scaling

If orders increase:

Order Service  = 20 Pods
Payment Service = 5 Pods

Only the busy service scales.

4. Fault Isolation

If Shipping Service crashes:

Shipping = Down
Orders = Working
Products = Working
Customers = Working

The whole application does not fail.

5. Technology Flexibility

Order Service      -> .NET
Payment Service    -> Java
Search Service     -> Node.js

Each capability can choose the best technology.

Challenges

Distributed Transactions

Example:

Order Created
Inventory Updated
Payment Failed

You need patterns like:

  • Saga Pattern
  • Event Sourcing
  • Compensation Transactions

Network Latency

Services communicate over the network instead of method calls.

Monitoring Complexity

Need tools such as:

  • OpenTelemetry
  • Application Insights
  • Grafana
  • ELK Stack

Interview Definition

Service Per Business Capability Pattern is a microservice design pattern where each microservice is organized around a single business capability, such as Orders, Payments, Inventory, or Customers. Each service owns its business logic, database, APIs, and deployment lifecycle, enabling independent development, deployment, and scaling while maintaining clear business boundaries.

Back to Index
Service Per Subdomain Pattern :👈 👉:Asynchronous Messaging Pattern