IConfiguration vs IOptions NET
Synchronous and Asynchronous in .NET Core
Model Binding and Validation in ASP.NET Core
ControllerBase vs Controller in ASP.NET Core
ConfigureServices and Configure methods
IHostedService interface in .NET Core
ASP.NET Core request processing
| Asynchronous Messaging Pattern :👈 | 👉:API Gateway Security |
Database per Service Pattern |
Database per Service is one of the fundamental microservices patterns.
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.
Consider an E-Commerce application with:
If all services use a single database:
Shared Database
│
┌───────────┬─────┼─────┬───────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Customer Order Payment Inventory
Service Service Service Service
Problems:
Order Service may directly access Customer tables.
SELECT * FROM Customers
Now Order Service depends on Customer Service's database structure.
Suppose Customer Service changes:
Customers
to
CustomerProfiles
Suddenly:
Order Service breaks Payment Service breaks Reporting Service breaks
Microservices should be independent.
With a shared database, changing one service affects others.
Instead of sharing a database:
API Gateway
│
┌──────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
Customer Order Payment
Service Service Service
│ │ │
▼ ▼ ▼
CustomerDB OrderDB PaymentDB
Each service owns its own database.
Responsible for:
Database:
CustomerDB
Tables:
Customers Addresses CustomerPreferences
Responsible for:
Database:
OrderDB
Tables:
Orders OrderItems OrderHistory
Responsible for:
Database:
PaymentDB
Tables:
Payments Refunds Transactions
Order Service
│
▼
Customer Service API
│
▼
CustomerDB
Order Service asks Customer Service through an API.
Order Service
│
▼
CustomerDB
Accessing another service's database directly breaks microservice boundaries.
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
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;"
}
}
public class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public decimal Amount { get; set; }
}
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.
Since databases are isolated, services must communicate through:
Example:
Order Service
│
▼
Customer Service API
GET /api/customers/1
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}");
}
}
Using:
Customer Service publishes:
CustomerCreated
Order Service subscribes.
Customer Service
│
▼
RabbitMQ
│
▼
Order Service
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.
Customer places an order.
Customer │ ▼ Order Service │ ▼ OrderDB
To validate customer:
Order Service
│
▼
Customer Service API
│
▼
CustomerDB
Order Service never touches CustomerDB directly.
Services remain independent.
Customer Service changes
↓
Order Service unaffected
Deploy Customer Service No impact on Order Service Payment Service
Order Service 20 instances Customer Service 5 instances
Each service scales as needed.
Database access can be restricted.
Customer Service
↓
Only service with access to CustomerDB
Each service can use:
SQL Server MySQL PostgreSQL MongoDB Cosmos DB
based on business needs.
Suppose:
Order Created Payment Failed
Data exists in multiple databases.
Traditional database transactions cannot span services easily.
Solution:
Need data from:
CustomerDB OrderDB PaymentDB
Since data is distributed, reporting becomes more complex.
Common solutions:
Instead of:
1 Database
you may have:
CustomerDB OrderDB PaymentDB InventoryDB ShippingDB
which increases operational overhead.
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.
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.
| Asynchronous Messaging Pattern :👈 | 👉:API Gateway Security |