Asynchronous Messaging Pattern :👈 👉:API Gateway Security

Database per Service Pattern

Database per Service Pattern in Microservices

Database per Service is one of the fundamental microservices patterns.

Definition

Each microservice owns its own private database, and no other service is allowed to access that database directly.

The service is the only authority for reading and writing its data.

Why Do We Need Database per Service?

Consider an E-Commerce application with:

  • Customer Service
  • Order Service
  • Payment Service
  • Inventory Service

If all services use a single database:

                Shared Database
                       │
     ┌───────────┬─────┼─────┬───────────┐
     │           │     │     │           │
     ▼           ▼     ▼     ▼           ▼
Customer    Order   Payment  Inventory
Service     Service Service  Service

Problems:

Tight Coupling

Order Service may directly access Customer tables.

SELECT *
FROM Customers

Now Order Service depends on Customer Service's database structure.

Schema Changes Become Risky

Suppose Customer Service changes:

Customers

to

CustomerProfiles

Suddenly:

Order Service breaks
Payment Service breaks
Reporting Service breaks

Independent Deployment Becomes Impossible

Microservices should be independent.

With a shared database, changing one service affects others.

Database per Service Architecture

Instead of sharing a database:

              API Gateway
                    │
 ┌──────────────────┼───────────────────┐
 │                  │                   │
 ▼                  ▼                   ▼
Customer       Order            Payment
 Service       Service          Service
    │             │                │
    ▼             ▼                ▼
CustomerDB     OrderDB       PaymentDB

Each service owns its own database.

Example: Online Shopping System

Customer Service

Responsible for:

  • Registration
  • Login
  • Profile Management

Database:

CustomerDB

Tables:

Customers
Addresses
CustomerPreferences

Order Service

Responsible for:

  • Creating Orders
  • Cancelling Orders
  • Tracking Orders

Database:

OrderDB

Tables:

Orders
OrderItems
OrderHistory

Payment Service

Responsible for:

  • Payments
  • Refunds
  • Transactions

Database:

PaymentDB

Tables:

Payments
Refunds
Transactions

Rule: Direct Database Access is Forbidden

✅ Correct

Order Service
      │
      ▼
Customer Service API
      │
      ▼
CustomerDB

Order Service asks Customer Service through an API.

❌ Wrong

Order Service
      │
      ▼
CustomerDB

Accessing another service's database directly breaks microservice boundaries.

.NET Example

Customer Service

Customer Entity

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

CustomerDbContext

public class CustomerDbContext : DbContext
{
    public CustomerDbContext(
        DbContextOptions<CustomerDbContext> options)
        : base(options)
    {
    }
    public DbSet<Customer> Customers { get; set; }
}

Connection String:

{
  "ConnectionStrings": {
    "CustomerDb":
    "Server=.;Database=CustomerDB;Trusted_Connection=True;"
  }
}

Order Service

Order Entity

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public decimal Amount { get; set; }
}

OrderDbContext

public class OrderDbContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
}

Connection String:

{
  "ConnectionStrings": {
    "OrderDb":
    "Server=.;Database=OrderDB;Trusted_Connection=True;"
  }
}

Notice that:

Customer Service -> CustomerDB
Order Service -> OrderDB

They are completely isolated.

How Services Share Data?

Since databases are isolated, services must communicate through:

1. REST APIs

Example:

Order Service
      │
      ▼
Customer Service API

Customer Service

GET /api/customers/1

.NET HttpClient

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

2. Event-Based Communication

Using:

  • RabbitMQ
  • Kafka
  • Azure Service Bus

Customer Service publishes:

CustomerCreated

Order Service subscribes.

Customer Service
        │
        ▼
     RabbitMQ
        │
        ▼
    Order Service

Different Database Technologies

Database per Service allows each service to choose the best database.

Example:

Customer Service
     │
     ▼
 SQL Server
Order Service
     │
     ▼
 PostgreSQL
Product Service
     │
     ▼
 MongoDB
Logging Service
     │
     ▼
 Elasticsearch

This is called Polyglot Persistence.

Example Workflow

Customer places an order.

Customer
   │
   ▼
Order Service
   │
   ▼
OrderDB

To validate customer:

Order Service
     │
     ▼
Customer Service API
     │
     ▼
CustomerDB

Order Service never touches CustomerDB directly.

Benefits

1. Loose Coupling

Services remain independent.

Customer Service changes
        ↓
Order Service unaffected

2. Independent Deployment

Deploy Customer Service
No impact on
Order Service
Payment Service

3. Independent Scaling

Order Service
20 instances
Customer Service
5 instances

Each service scales as needed.

4. Better Security

Database access can be restricted.

Customer Service
    ↓
Only service with access to CustomerDB

5. Technology Freedom

Each service can use:

SQL Server
MySQL
PostgreSQL
MongoDB
Cosmos DB

based on business needs.

Challenges

Data Consistency

Suppose:

Order Created
Payment Failed

Data exists in multiple databases.

Traditional database transactions cannot span services easily.

Solution:

  • Saga Pattern
  • Event-Driven Architecture
  • Compensation Transactions

Complex Reporting

Need data from:

CustomerDB
OrderDB
PaymentDB

Since data is distributed, reporting becomes more complex.

Common solutions:

  • Data Warehouse
  • Reporting Database
  • CQRS Read Models

More Infrastructure

Instead of:

1 Database

you may have:

CustomerDB
OrderDB
PaymentDB
InventoryDB
ShippingDB

which increases operational overhead.

Real-World Example

Amazon-like System

Customer Service  -> CustomerDB
Catalog Service   -> CatalogDB
Cart Service      -> CartDB
Order Service     -> OrderDB
Payment Service   -> PaymentDB
Shipping Service  -> ShippingDB
Review Service    -> ReviewDB

Every service owns its data and exposes APIs/events to other services.

Interview Answer

Database per Service is a microservice pattern where each microservice owns and manages its own private database. Other services cannot directly access that database and must communicate through APIs or messages/events. This pattern ensures loose coupling, independent deployment, independent scaling, better security, and clear ownership of data, making it a core principle of microservice architecture.

Back to Index
Asynchronous Messaging Pattern :👈 👉:API Gateway Security