> For the complete documentation index, see [llms.txt](https://docs.flexbase.in/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flexbase.in/core-concepts/modular-monolith-microservices.md).

# Modular Monolith / Microservices

## Overview

FlexBase provides a unique approach to application architecture that starts with a **modular monolith** by default and can seamlessly evolve into **true microservices** when needed. This evolutionary architecture pattern allows you to start simple and scale to enterprise levels without the complexity of microservices from day one.

## The Evolution Path

```
Phase 1: Modular Monolith    →    Phase 2: Distributed Monolith    →    Phase 3: True Microservices
     (Single Application)              (Shared Database)                    (Independent Services)
```

**FlexBase Philosophy**: Start with a modular monolith, evolve to microservices when business requirements demand it.

## Modular Monolith: The FlexBase Default

### **What is a Modular Monolith?**

A modular monolith is a single application that is internally organized into **loosely coupled modules**. Each module has clear boundaries and can be developed, tested, and deployed independently, but they all run within the same process.

#### **FlexBase Modular Monolith Structure**

```
┌─────────────────────────────────────────────────────────────────┐
│                    FlexBase Modular Monolith                    │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────┐ │
│  │   ECommerce │  │   Payment   │  │   Shipping  │  │  User   │ │
│  │   Module    │  │   Module    │  │   Module    │  │ Module  │ │
│  ├─────────────┤  ├─────────────┤  ├─────────────┤  ├─────────┤ │
│  │ • Orders    │  │ • Payments  │  │ • Shipments │  │ • Users │ │
│  │ • Products  │  │ • Refunds   │  │ • Tracking  │  │ • Auth  │ │
│  │ • Inventory │  │ • Billing   │  │ • Logistics │  │ • Roles │ │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────┘ │
├─────────────────────────────────────────────────────────────────┤
│                    Shared Database Layer                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────┐ │
│  │   Orders    │  │  Payments   │  │  Shipments  │  │  Users  │ │
│  │   Tables    │  │   Tables    │  │   Tables    │  │ Tables  │ │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────┘ │
└─────────────────────────────────────────────────────────────────┘
```

### **FlexBase Modular Monolith Benefits**

#### **1. Clear Module Boundaries**

```csharp
// ECommerce Module
namespace EBusiness.Modules.ECommerce
{
    public class OrdersController : ControllerBase
    {
        [HttpPost]
        public async Task<IActionResult> CreateOrder(OrderDto order)
        {
            return await RunService(201, order, _processOrdersService.CreateOrder);
        }
    }
}

// Payment Module
namespace EBusiness.Modules.Payment
{
    public class PaymentsController : ControllerBase
    {
        [HttpPost]
        public async Task<IActionResult> ProcessPayment(PaymentDto payment)
        {
            return await RunService(200, payment, _processPaymentsService.ProcessPayment);
        }
    }
}
```

#### **2. Independent Module Development**

* **Separate Teams**: Each module can be developed by different teams
* **Independent Testing**: Test each module in isolation
* **Module-Specific Dependencies**: Each module manages its own dependencies
* **Clear Interfaces**: Well-defined contracts between modules

#### **3. Shared Infrastructure**

* **Single Database**: All modules share the same database
* **Shared Message Bus**: Common message queue for inter-module communication
* **Unified Monitoring**: Single monitoring and logging system
* **Common Configuration**: Shared configuration management

### **FlexBase Module Communication Patterns**

#### **1. Synchronous Communication (Within Monolith)**

```csharp
// Direct service calls within the same application
public class OrderService
{
    private readonly IPaymentService _paymentService;
    private readonly IInventoryService _inventoryService;

    public async Task<Order> CreateOrder(OrderDto order)
    {
        // Synchronous calls within the same process
        await _inventoryService.ReserveInventory(order.Items);
        var payment = await _paymentService.ProcessPayment(order.Payment);
        
        return await SaveOrder(order, payment);
    }
}
```

#### **2. Asynchronous Communication (Event-Driven)**

```csharp
// Event-driven communication between modules
public class OrderCreatedHandler : IOrderCreatedHandler
{
    public async Task Execute(OrderCreatedEvent @event, IFlexServiceBusContext context)
    {
        // Fire events to other modules
        await this.Fire<InventoryReservationCommand>(EventCondition, context);
        await this.Fire<PaymentProcessingCommand>(EventCondition, context);
        await this.Fire<ShippingNotificationCommand>(EventCondition, context);
    }
}
```

### **Modular Monolith Advantages**

#### **1. Development Simplicity**

* **Single Deployment**: Deploy one application
* **Shared Dependencies**: Common libraries and frameworks
* **Unified Testing**: Test the entire application together
* **Simple Debugging**: Single process to debug

#### **2. Performance Benefits**

* **No Network Overhead**: Direct method calls
* **Shared Memory**: Efficient data sharing
* **Single Database Connection**: Reduced connection overhead
* **Fast Communication**: In-process communication

#### **3. Operational Simplicity**

* **Single Monitoring**: One application to monitor
* **Unified Logging**: All logs in one place
* **Simple Deployment**: One deployment pipeline
* **Easy Rollback**: Single application rollback

## True Microservices: The Next Evolution

### **When to Evolve to Microservices**

#### **Business Triggers**

* **Team Growth**: Multiple teams need independent deployment
* **Technology Diversity**: Different modules need different technologies
* **Scaling Requirements**: Different modules have different scaling needs
* **Geographic Distribution**: Modules need to be deployed in different regions

#### **Technical Triggers**

* **Database Bottlenecks**: Single database becomes a bottleneck
* **Deployment Conflicts**: Teams block each other during deployments
* **Technology Constraints**: Different modules need different tech stacks
* **Performance Isolation**: Need to isolate performance issues

### **FlexBase Microservices Architecture**

#### **True Microservices Structure**

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  ECommerce      │    │  Payment        │    │  Shipping       │    │  User           │
│  Microservice   │    │  Microservice   │    │  Microservice   │    │  Microservice   │
├─────────────────┤    ├─────────────────┤    ├─────────────────┤    ├─────────────────┤
│ • Orders API    │    │ • Payments API  │    │ • Shipping API  │    │ • Users API     │
│ • Products API  │    │ • Billing API   │    │ • Tracking API  │    │ • Auth API      │
│ • Inventory API │    │ • Refunds API   │    │ • Logistics API │    │ • Roles API     │
└─────────────────┘    └─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │                       │
         ▼                       ▼                       ▼                       ▼
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  ECommerce DB   │    │  Payment DB     │    │  Shipping DB    │    │  User DB        │
│  (Independent)  │    │  (Independent)  │    │  (Independent)  │    │  (Independent)  │
└─────────────────┘    └─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │                       │
         └───────────────────────┼───────────────────────┼───────────────────────┘
                                 │                       │
                                 ▼                       ▼
                    ┌─────────────────┐    ┌─────────────────┐
                    │  Message Bus    │    │  API Gateway    │
                    │  (Events)       │    │  (Routing)      │
                    └─────────────────┘    └─────────────────┘
```

### **FlexBase Microservices Implementation**

Each microservice is a **completely independent FlexBase application** with its own:

* **Database**: Independent database schema and data
* **Message Bus**: Own message queue configuration
* **Endpoints**: Separate WebAPI, Handlers, and Subscribers
* **Configuration**: Independent appsettings and environment configs
* **Deployment**: Independent deployment pipeline
* **Scaling**: Independent scaling configuration

#### **1. ECommerce Microservice - Independent FlexBase Application**

**Project Structure:**

```
ECommerce.Service/
├── ECommerce.EndPoint.WebAPI/          # WebAPI Endpoint
├── ECommerce.EndPoint.Handlers/        # Command Handlers
├── ECommerce.EndPoint.Subscribers/     # Event Subscribers
├── ECommerce.Domain/                   # Domain Models
├── ECommerce.Application/              # Application Services
└── ECommerce.Infrastructure/           # Database & Message Bus
```

**WebAPI Endpoint:**

```csharp
// ECommerce Microservice - Independent FlexBase Application
namespace ECommerce.Service.EndPoint.WebAPI
{
    public class OrdersController : ControllerBase
    {
        [HttpPost]
        public async Task<IActionResult> CreateOrder(OrderDto order)
        {
            // Process order using FlexBase patterns
            return await RunService(201, order, _processOrdersService.CreateOrder);
        }
        
        [HttpGet]
        public async Task<IActionResult> GetOrder(string orderId)
        {
            return await RunService(200, new GetOrderDto { Id = orderId }, _queryOrdersService.GetOrderById);
        }
    }
}
```

**Command Handler:**

```csharp
// ECommerce Command Handler - Independent Processing
public class CreateOrderHandler : ICreateOrderHandler
{
    public async Task Execute(CreateOrderCommand cmd, IFlexServiceBusContext context)
    {
        // Process order in ECommerce service
        _model = _flexHost.GetDomainModel<Order>().CreateOrder(cmd);
        _repoFactory.GetRepo().InsertOrUpdate(_model);
        await _repoFactory.GetRepo().SaveAsync();
        
        // Publish event to other microservices
        await this.Fire<OrderCreatedEvent>(EventCondition, context);
    }
}
```

**Configuration:**

```json
{
  "FlexBase": {
    "AppDbConnection": "Data Source=localhost;Initial Catalog=ECommerceDb;...",
    "AppReadDbConnection": "Data Source=localhost;Initial Catalog=ECommerceReadDb;...",
    "RabbitMqConnectionString": "amqp://localhost:5672/ecommerce"
  }
}
```

#### **2. Payment Microservice - Independent FlexBase Application**

**Project Structure:**

```
Payment.Service/
├── Payment.EndPoint.WebAPI/            # WebAPI Endpoint
├── Payment.EndPoint.Handlers/          # Command Handlers
├── Payment.EndPoint.Subscribers/       # Event Subscribers
├── Payment.Domain/                     # Domain Models
├── Payment.Application/                # Application Services
└── Payment.Infrastructure/             # Database & Message Bus
```

**WebAPI Endpoint:**

```csharp
// Payment Microservice - Independent FlexBase Application
namespace Payment.Service.EndPoint.WebAPI
{
    public class PaymentsController : ControllerBase
    {
        [HttpPost]
        public async Task<IActionResult> ProcessPayment(PaymentDto payment)
        {
            // Process payment using FlexBase patterns
            return await RunService(200, payment, _processPaymentsService.ProcessPayment);
        }
        
        [HttpGet]
        public async Task<IActionResult> GetPayment(string paymentId)
        {
            return await RunService(200, new GetPaymentDto { Id = paymentId }, _queryPaymentsService.GetPaymentById);
        }
    }
}
```

**Event Subscriber:**

```csharp
// Payment Event Subscriber - Reacts to ECommerce Events
public class OrderCreatedHandler : IOrderCreatedHandler
{
    public async Task Execute(OrderCreatedEvent @event, IFlexServiceBusContext context)
    {
        // Process payment for the order
        var paymentCommand = new ProcessPaymentCommand
        {
            OrderId = @event.OrderId,
            Amount = @event.TotalAmount,
            CustomerId = @event.CustomerId
        };
        
        await _processPaymentsService.ProcessPayment(paymentCommand);
    }
}
```

**Configuration:**

```json
{
  "FlexBase": {
    "AppDbConnection": "Data Source=localhost;Initial Catalog=PaymentDb;...",
    "AppReadDbConnection": "Data Source=localhost;Initial Catalog=PaymentReadDb;...",
    "RabbitMqConnectionString": "amqp://localhost:5672/payment"
  }
}
```

#### **3. Shipping Microservice - Independent FlexBase Application**

**Project Structure:**

```
Shipping.Service/
├── Shipping.EndPoint.WebAPI/           # WebAPI Endpoint
├── Shipping.EndPoint.Handlers/         # Command Handlers
├── Shipping.EndPoint.Subscribers/      # Event Subscribers
├── Shipping.Domain/                    # Domain Models
├── Shipping.Application/               # Application Services
└── Shipping.Infrastructure/            # Database & Message Bus
```

**WebAPI Endpoint:**

```csharp
// Shipping Microservice - Independent FlexBase Application
namespace Shipping.Service.EndPoint.WebAPI
{
    public class ShipmentsController : ControllerBase
    {
        [HttpPost]
        public async Task<IActionResult> CreateShipment(ShipmentDto shipment)
        {
            // Process shipment using FlexBase patterns
            return await RunService(201, shipment, _processShipmentsService.CreateShipment);
        }
        
        [HttpGet]
        public async Task<IActionResult> TrackShipment(string trackingNumber)
        {
            return await RunService(200, new TrackShipmentDto { TrackingNumber = trackingNumber }, _queryShipmentsService.TrackShipment);
        }
    }
}
```

**Event Subscriber:**

```csharp
// Shipping Event Subscriber - Reacts to Payment Events
public class PaymentProcessedHandler : IPaymentProcessedHandler
{
    public async Task Execute(PaymentProcessedEvent @event, IFlexServiceBusContext context)
    {
        if (@event.Status == PaymentStatus.Success)
        {
            // Create shipment for paid order
            var shipmentCommand = new CreateShipmentCommand
            {
                OrderId = @event.OrderId,
                CustomerId = @event.CustomerId,
                Items = @event.Items
            };
            
            await _processShipmentsService.CreateShipment(shipmentCommand);
        }
    }
}
```

**Configuration:**

```json
{
  "FlexBase": {
    "AppDbConnection": "Data Source=localhost;Initial Catalog=ShippingDb;...",
    "AppReadDbConnection": "Data Source=localhost;Initial Catalog=ShippingReadDb;...",
    "RabbitMqConnectionString": "amqp://localhost:5672/shipping"
  }
}
```

#### **3. Event-Driven Communication**

```csharp
// ECommerce Microservice - Event Handler
public class PaymentProcessedHandler : IPaymentProcessedHandler
{
    public async Task Execute(PaymentProcessedEvent @event, IFlexServiceBusContext context)
    {
        // Update order status based on payment
        if (@event.Status == PaymentStatus.Success)
        {
            await _orderService.UpdateOrderStatus(@event.OrderId, OrderStatus.Paid);
            await this.Fire<OrderPaidEvent>(EventCondition, context);
        }
        else
        {
            await _orderService.UpdateOrderStatus(@event.OrderId, OrderStatus.PaymentFailed);
            await this.Fire<OrderPaymentFailedEvent>(EventCondition, context);
        }
    }
}
```

## Microservices Aggregator: Consolidating Services for Clients

### **The Aggregator Pattern**

When you have multiple independent FlexBase microservices, you need an **Aggregator Service** to consolidate data and provide a unified API for client applications. The aggregator acts as a **composite service** that orchestrates calls to multiple microservices and combines their responses.

#### **Aggregator Architecture**

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Client App    │    │   Mobile App    │    │   Web App       │
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │
         └───────────────────────┼───────────────────────┘
                                 │
                    ┌─────────────────┐
                    │   Aggregator    │
                    │   Service       │
                    │  (FlexBase)     │
                    └─────────────────┘
                                 │
         ┌───────────────────────┼───────────────────────┐
         │                       │                       │
         ▼                       ▼                       ▼
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  ECommerce      │    │  Payment        │    │  Shipping       │
│  Microservice   │    │  Microservice   │    │  Microservice   │
└─────────────────┘    └─────────────────┘    └─────────────────┘
```

### **FlexBase Aggregator Service Implementation**

#### **Aggregator Project Structure**

```
Aggregator.Service/
├── Aggregator.EndPoint.WebAPI/         # WebAPI Endpoint
├── Aggregator.EndPoint.Handlers/       # Command Handlers
├── Aggregator.EndPoint.Subscribers/    # Event Subscribers
├── Aggregator.Application/             # Aggregation Services
├── Aggregator.Infrastructure/          # HTTP Clients & Configuration
└── Aggregator.Shared/                  # Shared DTOs & Models
```

#### **Aggregator Controller - Unified API**

```csharp
// Aggregator Service - Consolidates Multiple Microservices
namespace Aggregator.Service.EndPoint.WebAPI
{
    [ApiController]
    [Route("api/[controller]")]
    public class OrdersController : ControllerBase
    {
        private readonly IOrderAggregationService _orderAggregationService;

        [HttpPost]
        public async Task<IActionResult> CreateOrder(CreateOrderRequest request)
        {
            // Orchestrate order creation across multiple services
            var result = await _orderAggregationService.CreateOrderAsync(request);
            return Ok(result);
        }

        [HttpGet("{orderId}")]
        public async Task<IActionResult> GetOrderDetails(string orderId)
        {
            // Aggregate data from multiple services
            var orderDetails = await _orderAggregationService.GetOrderDetailsAsync(orderId);
            return Ok(orderDetails);
        }

        [HttpGet("{orderId}/status")]
        public async Task<IActionResult> GetOrderStatus(string orderId)
        {
            // Get comprehensive order status
            var status = await _orderAggregationService.GetOrderStatusAsync(orderId);
            return Ok(status);
        }
    }
}
```

#### **Order Aggregation Service**

```csharp
// Order Aggregation Service - Orchestrates Multiple Microservices
public class OrderAggregationService : IOrderAggregationService
{
    private readonly IECommerceServiceClient _ecommerceClient;
    private readonly IPaymentServiceClient _paymentClient;
    private readonly IShippingServiceClient _shippingClient;

    public async Task<OrderDetailsResponse> GetOrderDetailsAsync(string orderId)
    {
        // Parallel calls to multiple microservices
        var orderTask = _ecommerceClient.GetOrderAsync(orderId);
        var paymentTask = _paymentClient.GetPaymentByOrderIdAsync(orderId);
        var shipmentTask = _shippingClient.GetShipmentByOrderIdAsync(orderId);

        await Task.WhenAll(orderTask, paymentTask, shipmentTask);

        // Aggregate responses
        return new OrderDetailsResponse
        {
            Order = await orderTask,
            Payment = await paymentTask,
            Shipment = await shipmentTask,
            Status = DetermineOverallStatus(await orderTask, await paymentTask, await shipmentTask)
        };
    }

    public async Task<CreateOrderResponse> CreateOrderAsync(CreateOrderRequest request)
    {
        // Step 1: Create order in ECommerce service
        var orderResult = await _ecommerceClient.CreateOrderAsync(new CreateOrderDto
        {
            CustomerId = request.CustomerId,
            Items = request.Items,
            TotalAmount = request.TotalAmount
        });

        // Step 2: Process payment
        var paymentResult = await _paymentClient.ProcessPaymentAsync(new ProcessPaymentDto
        {
            OrderId = orderResult.OrderId,
            Amount = orderResult.TotalAmount,
            PaymentMethod = request.PaymentMethod
        });

        // Step 3: Create shipment if payment successful
        ShipmentDto shipmentResult = null;
        if (paymentResult.Status == PaymentStatus.Success)
        {
            shipmentResult = await _shippingClient.CreateShipmentAsync(new CreateShipmentDto
            {
                OrderId = orderResult.OrderId,
                CustomerId = request.CustomerId,
                Items = request.Items
            });
        }

        return new CreateOrderResponse
        {
            OrderId = orderResult.OrderId,
            PaymentId = paymentResult.PaymentId,
            ShipmentId = shipmentResult?.ShipmentId,
            Status = DetermineOrderStatus(orderResult, paymentResult, shipmentResult)
        };
    }
}
```

#### **HTTP Client Services**

```csharp
// ECommerce Service Client
public class ECommerceServiceClient : IECommerceServiceClient
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<ECommerceServiceClient> _logger;

    public async Task<OrderDto> GetOrderAsync(string orderId)
    {
        var response = await _httpClient.GetAsync($"/api/orders/{orderId}");
        response.EnsureSuccessStatusCode();
        
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<OrderDto>(content);
    }

    public async Task<CreateOrderResponse> CreateOrderAsync(CreateOrderDto order)
    {
        var json = JsonSerializer.Serialize(order);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await _httpClient.PostAsync("/api/orders", content);
        response.EnsureSuccessStatusCode();
        
        var responseContent = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<CreateOrderResponse>(responseContent);
    }
}

// Payment Service Client
public class PaymentServiceClient : IPaymentServiceClient
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<PaymentServiceClient> _logger;

    public async Task<PaymentDto> GetPaymentByOrderIdAsync(string orderId)
    {
        var response = await _httpClient.GetAsync($"/api/payments/order/{orderId}");
        response.EnsureSuccessStatusCode();
        
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<PaymentDto>(content);
    }

    public async Task<ProcessPaymentResponse> ProcessPaymentAsync(ProcessPaymentDto payment)
    {
        var json = JsonSerializer.Serialize(payment);
        var content = new StringContent(json, Encoding.UTF8, "application/json");
        
        var response = await _httpClient.PostAsync("/api/payments", content);
        response.EnsureSuccessStatusCode();
        
        var responseContent = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<ProcessPaymentResponse>(responseContent);
    }
}
```

#### **Aggregator Configuration**

```json
{
  "FlexBase": {
    "AppDbConnection": "Data Source=localhost;Initial Catalog=AggregatorDb;...",
    "AppReadDbConnection": "Data Source=localhost;Initial Catalog=AggregatorReadDb;...",
    "RabbitMqConnectionString": "amqp://localhost:5672/aggregator"
  },
  "Microservices": {
    "ECommerce": {
      "BaseUrl": "https://ecommerce-service.yourcompany.com",
      "ApiKey": "your-ecommerce-api-key",
      "Timeout": "00:00:30"
    },
    "Payment": {
      "BaseUrl": "https://payment-service.yourcompany.com",
      "ApiKey": "your-payment-api-key",
      "Timeout": "00:00:30"
    },
    "Shipping": {
      "BaseUrl": "https://shipping-service.yourcompany.com",
      "ApiKey": "your-shipping-api-key",
      "Timeout": "00:00:30"
    }
  }
}
```

#### **HTTP Client Registration**

```csharp
// Program.cs - Register HTTP Clients
public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Register HTTP clients for microservices
        builder.Services.AddHttpClient<IECommerceServiceClient, ECommerceServiceClient>(client =>
        {
            var config = builder.Configuration.GetSection("Microservices:ECommerce");
            client.BaseAddress = new Uri(config["BaseUrl"]);
            client.DefaultRequestHeaders.Add("X-API-Key", config["ApiKey"]);
            client.Timeout = TimeSpan.Parse(config["Timeout"]);
        });

        builder.Services.AddHttpClient<IPaymentServiceClient, PaymentServiceClient>(client =>
        {
            var config = builder.Configuration.GetSection("Microservices:Payment");
            client.BaseAddress = new Uri(config["BaseUrl"]);
            client.DefaultRequestHeaders.Add("X-API-Key", config["ApiKey"]);
            client.Timeout = TimeSpan.Parse(config["Timeout"]);
        });

        builder.Services.AddHttpClient<IShippingServiceClient, ShippingServiceClient>(client =>
        {
            var config = builder.Configuration.GetSection("Microservices:Shipping");
            client.BaseAddress = new Uri(config["BaseUrl"]);
            client.DefaultRequestHeaders.Add("X-API-Key", config["ApiKey"]);
            client.Timeout = TimeSpan.Parse(config["Timeout"]);
        });

        // Register aggregation services
        builder.Services.AddScoped<IOrderAggregationService, OrderAggregationService>();

        var app = builder.Build();
        app.Run();
    }
}
```

### **Aggregator Benefits**

#### **1. Unified API for Clients**

* **Single Endpoint**: Clients call one API instead of multiple microservices
* **Consistent Interface**: Standardized request/response format
* **Simplified Integration**: Easier for client applications to integrate

#### **2. Data Aggregation**

* **Combined Responses**: Merge data from multiple services
* **Business Logic**: Implement cross-service business rules
* **Data Transformation**: Convert service-specific data to client-friendly format

#### **3. Error Handling & Resilience**

* **Circuit Breaker**: Handle service failures gracefully
* **Retry Logic**: Retry failed calls with exponential backoff
* **Fallback Data**: Provide partial data when some services are unavailable

#### **4. Performance Optimization**

* **Parallel Calls**: Make concurrent calls to multiple services
* **Caching**: Cache frequently accessed data
* **Response Compression**: Compress responses for better performance

### **Microservices Communication Patterns**

#### **1. API Gateway Pattern**

```yaml
# API Gateway Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-gateway
spec:
  rules:
  - host: api.yourcompany.com
    http:
      paths:
      - path: /api/orders
        pathType: Prefix
        backend:
          service:
            name: aggregator-service
            port:
              number: 80
      - path: /ecommerce
        pathType: Prefix
        backend:
          service:
            name: ecommerce-service
            port:
              number: 80
      - path: /payment
        pathType: Prefix
        backend:
          service:
            name: payment-service
            port:
              number: 80
      - path: /shipping
        pathType: Prefix
        backend:
          service:
            name: shipping-service
            port:
              number: 80
```

#### **2. Event-Driven Communication**

```csharp
// Event Bus Configuration
public class EventBusConfiguration
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddNServiceBus(cfg =>
        {
            cfg.Transport(transport =>
            {
                transport.UseRabbitMQ(connectionString: "amqp://localhost:5672");
            });
            
            cfg.Routing(routing =>
            {
                routing.RouteToEndpoint(typeof(OrderCreatedEvent), "ECommerce.Service");
                routing.RouteToEndpoint(typeof(PaymentProcessedEvent), "Payment.Service");
                routing.RouteToEndpoint(typeof(ShippingCreatedEvent), "Shipping.Service");
            });
        });
    }
}
```

#### **3. Database per Service**

```csharp
// Each microservice has its own database
public class ECommerceDbContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
    public DbSet<Product> Products { get; set; }
    public DbSet<Inventory> Inventory { get; set; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(Configuration.GetConnectionString("ECommerceDb"));
    }
}

public class PaymentDbContext : DbContext
{
    public DbSet<Payment> Payments { get; set; }
    public DbSet<Refund> Refunds { get; set; }
    public DbSet<Billing> Billing { get; set; }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(Configuration.GetConnectionString("PaymentDb"));
    }
}
```

### **Microservices Advantages**

#### **1. Independent Deployment**

* **Team Autonomy**: Each team can deploy independently
* **Technology Freedom**: Use different technologies per service
* **Scaling Independence**: Scale each service based on its needs
* **Fault Isolation**: Failure in one service doesn't affect others

#### **2. Technology Diversity**

```csharp
// ECommerce Service - .NET Core
public class OrdersController : ControllerBase { }

// Payment Service - Node.js
app.post('/api/payments', (req, res) => { });

// Shipping Service - Python
@app.route('/api/shipping', methods=['POST'])
def create_shipment(): pass
```

#### **3. Data Independence**

* **Database per Service**: Each service owns its data
* **Data Consistency**: Eventual consistency through events
* **Technology Choice**: Different databases per service
* **Independent Schema**: Evolve schemas independently

## Migration Strategy: From Modular Monolith to Microservices

### **Phase 1: Identify Service Boundaries**

#### **Domain Analysis**

```csharp
// Analyze existing modules for service boundaries
public class ServiceBoundaryAnalysis
{
    public List<ServiceCandidate> AnalyzeModules()
    {
        return new List<ServiceCandidate>
        {
            new ServiceCandidate
            {
                Name = "ECommerce",
                Modules = new[] { "Orders", "Products", "Inventory" },
                Dependencies = new[] { "Payment", "Shipping" },
                DataVolume = "High",
                ChangeFrequency = "High"
            },
            new ServiceCandidate
            {
                Name = "Payment",
                Modules = new[] { "Payments", "Refunds", "Billing" },
                Dependencies = new[] { "ECommerce" },
                DataVolume = "Medium",
                ChangeFrequency = "Low"
            }
        };
    }
}
```

### **Phase 2: Extract Services Gradually**

#### **Strangler Fig Pattern**

```csharp
// Gradually replace monolith functionality with microservices
public class OrderService
{
    private readonly IOrderService _legacyOrderService;
    private readonly IOrderService _newOrderService;
    private readonly bool _useNewService;

    public async Task<Order> CreateOrder(OrderDto order)
    {
        if (_useNewService)
        {
            return await _newOrderService.CreateOrder(order);
        }
        else
        {
            return await _legacyOrderService.CreateOrder(order);
        }
    }
}
```

### **Phase 3: Implement Event-Driven Communication**

#### **Event Sourcing Pattern**

```csharp
// Implement event sourcing for data consistency
public class OrderAggregate
{
    private readonly List<IDomainEvent> _events = new();
    
    public void CreateOrder(OrderDto order)
    {
        // Apply business logic
        var orderCreated = new OrderCreatedEvent
        {
            OrderId = Guid.NewGuid(),
            CustomerId = order.CustomerId,
            Items = order.Items
        };
        
        // Store event
        _events.Add(orderCreated);
    }
    
    public IEnumerable<IDomainEvent> GetUncommittedEvents()
    {
        return _events;
    }
}
```

## FlexBase: The Best of Both Worlds

### **Why FlexBase is Perfect for This Evolution**

#### **1. Built-in Modularity**

* **Endpoint Architecture**: Natural service boundaries
* **Event-Driven**: Ready for microservices communication
* **CQRS Pattern**: Independent read/write operations
* **Message Queues**: Built-in asynchronous communication

#### **2. Seamless Migration**

* **Same Code**: Business logic remains unchanged
* **Configuration-Driven**: Switch between monolith and microservices
* **Gradual Evolution**: Move modules to microservices one by one
* **Risk Mitigation**: Test each migration step independently

#### **3. Operational Excellence**

* **Unified Monitoring**: Same monitoring for both architectures
* **Consistent Patterns**: Same development patterns
* **Shared Infrastructure**: Leverage existing infrastructure
* **Team Training**: Minimal learning curve for teams

### **FlexBase Configuration for Architecture Evolution**

#### **Modular Monolith Configuration**

```json
{
  "FlexBase": {
    "Architecture": "ModularMonolith",
    "Database": {
      "Type": "Single",
      "ConnectionString": "Data Source=localhost;Initial Catalog=YourApp;..."
    },
    "MessageBus": {
      "Type": "InProcess",
      "Configuration": "Local"
    }
  }
}
```

#### **Microservices Configuration**

```json
{
  "FlexBase": {
    "Architecture": "Microservices",
    "Services": {
      "ECommerce": {
        "Database": "Data Source=localhost;Initial Catalog=ECommerceDb;...",
        "MessageBus": "amqp://localhost:5672"
      },
      "Payment": {
        "Database": "Data Source=localhost;Initial Catalog=PaymentDb;...",
        "MessageBus": "amqp://localhost:5672"
      }
    }
  }
}
```

## Real-World Examples

### **E-Commerce Platform Evolution**

#### **Phase 1: Modular Monolith (Startup)**

* **Team Size**: 5 developers
* **Deployment**: Single application
* **Database**: Single SQL Server
* **Communication**: Direct method calls
* **Cost**: $500/month

#### **Phase 2: Distributed Monolith (Growth)**

* **Team Size**: 15 developers
* **Deployment**: Single application with load balancing
* **Database**: Single database with read replicas
* **Communication**: Events + direct calls
* **Cost**: $2,000/month

#### **Phase 3: Microservices (Scale)**

* **Team Size**: 50+ developers
* **Deployment**: Independent services
* **Database**: Database per service
* **Communication**: Event-driven only
* **Cost**: $10,000/month

### **Financial Services Evolution**

#### **Modular Monolith Benefits**

* **Compliance**: Single audit trail
* **Security**: Unified security model
* **Development**: Fast feature development
* **Testing**: Comprehensive integration testing

#### **Microservices Benefits**

* **Regulatory**: Independent compliance per service
* **Security**: Isolated security per service
* **Scalability**: Scale payment processing independently
* **Technology**: Use specialized financial technologies

## Best Practices

### **1. Start with Modular Monolith**

* **Clear Boundaries**: Define module boundaries early
* **Event-Driven**: Use events from the beginning
* **Database Design**: Design for future service extraction
* **API Design**: Design APIs as if they were separate services

### **2. Plan for Microservices Evolution**

* **Service Identification**: Identify potential services early
* **Data Ownership**: Plan data ownership per service
* **Communication Patterns**: Use event-driven communication
* **Technology Choices**: Choose technologies that support both architectures

### **3. Migration Strategy**

* **Gradual Migration**: Move one module at a time
* **Feature Flags**: Use feature flags for gradual rollout
* **Testing**: Test each migration step thoroughly
* **Rollback Plan**: Always have a rollback strategy

### **4. Operational Considerations**

* **Monitoring**: Implement comprehensive monitoring
* **Logging**: Centralized logging across all services
* **Security**: Consistent security model
* **Deployment**: Automated deployment pipelines

## Conclusion

FlexBase provides the perfect foundation for both **modular monoliths** and **true microservices**. By starting with a modular monolith, you get the benefits of simplicity and performance while maintaining the flexibility to evolve to microservices when business requirements demand it.

**The FlexBase Advantage:**

* **Start Simple**: Begin with modular monolith
* **Evolve Naturally**: Move to microservices when needed
* **Same Code**: Business logic remains unchanged
* **Risk Mitigation**: Gradual, tested evolution
* **Best of Both Worlds**: Simplicity when you need it, scalability when you want it

***

**Ready to build applications that can evolve with your business? Start with FlexBase and let your architecture grow with your needs!** 🚀
