> 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/solution-structure/getting-started/features/rest-services/insert-example.md).

# Insert Example

## Overview

This document demonstrates the complete **Insert flow** using the **AddToShipping** feature from the EBusiness application. The flow starts with a POST request to the controller and ends with event publishing and subscriber processing.

## Complete Flow Architecture

```
POST Request → Controller → Service → PreBus Plugins → Command Handler → RESTClient → External System
                                                                                    ↓
Response ← Controller ← Service ← Command Handler ← RESTClient ← External System
```

### **Detailed Flow Breakdown**

```
1. POST Request
   ↓
2. Controller (API Entry Point)
   ↓
3. Service Layer (Business Orchestration)
   ↓
4. PreBus Processing (Validation Pipeline)
   ├── AddToShippingSequence (Plugin Registration)
   ├── AddToShippingDataPacket (Validation Context)
   └── ValidateShipping Plugin (Business Rules)
   ↓
5. Command Handler (RESTClient Integration)
   ├── Internal DTO → Request DTO Mapping
   ├── RESTClient Call to External System
   └── Response DTO Processing
   ↓
6. Event Publishing (Asynchronous Processing)
   ↓
7. Subscribers (Side Effects)
```

## Step-by-Step Implementation

### 1. **API Controller** - The Entry Point

**File**: `ShippingController_AddToShipping.cs`

```csharp
[HttpPost]
[Route("AddToShipping")]
[ProducesResponseType(typeof(BadRequestResult), 400)]
[ProducesResponseType(typeof(string), 201)]
public async Task<IActionResult> AddToShipping([FromBody]AddToShippingDto dto)
{
    return await RunService(201, dto, _processShippingService.AddToShipping);
}
```

**What Happens:**

* **HTTP Method**: `POST /api/Shipping/AddToShipping`
* **Input**: `AddToShippingDto` from request body
* **Action**: Calls the service layer to process the shipping
* **Response**: HTTP 201 Created with shipping ID

### 2. **Service Layer** - Business Orchestration

**File**: `ProcessShippingService_AddToShipping.cs`

```csharp
public async Task<CommandResult> AddToShipping(AddToShippingDto dto)
{
    var packet = await ProcessBusinessRuleSequence<AddToShippingDataPacket, AddToShippingSequence, AddToShippingDto, FlexAppContextBridge>(dto);

    if (packet.HasError)
    {
        return new CommandResult(Status.Failed, packet.Errors());
    }
    else
    {
        dto.SetGeneratedId(_pkGenerator.GenerateKey());
        AddToShippingCommand cmd = new AddToShippingCommand
        {
             Dto = dto,
        };

        await ProcessCommand(cmd);

        CommandResult cmdResult = new CommandResult(Status.Success);

        AddToShippingResultModel outputResult = new AddToShippingResultModel();
        outputResult.Id = dto.GetGeneratedId();
        cmdResult.result = outputResult;

        return cmdResult;
    }
}
```

**What Happens:**

* **PreBus Processing**: Executes business rule sequences (plugins)
* **Validation**: Processes business rule sequences
* **ID Generation**: Generates unique shipping ID
* **Command Creation**: Creates `AddToShippingCommand` with DTO
* **Command Processing**: Calls the command handler
* **Result**: Returns success with generated shipping ID

### 2.1. **PreBus Business Rule Sequence** - Validation Pipeline

**File**: `AddToShippingSequence.cs`

```csharp
public class AddToShippingSequence : FlexiBusinessRuleSequenceBase<AddToShippingDataPacket>
{
    public AddToShippingSequence()
    {
        this.Add<ValidateShipping>(); 
    }
}
```

**What Happens:**

* **Plugin Registration**: Registers validation plugins in execution order
* **Sequential Processing**: Executes plugins one by one
* **Error Collection**: Collects validation errors from all plugins
* **Early Exit**: Stops processing if any plugin fails

### 2.2. **PreBus Data Packet** - Validation Context

**File**: `AddToShippingDataPacket.cs`

```csharp
public partial class AddToShippingDataPacket : FlexiFlowDataPacketWithDtoBridge<AddToShippingDto, FlexAppContextBridge>
{
    protected readonly ILogger<AddToShippingDataPacket> _logger;

    public AddToShippingDataPacket(ILogger<AddToShippingDataPacket> logger)
    {
        _logger = logger;
    }

    #region "Properties
    //Models and other properties goes here
    #endregion
}
```

**What Happens:**

* **Context Container**: Holds DTO and application context
* **Error Collection**: Collects validation errors from plugins
* **Data Sharing**: Allows plugins to share data during validation
* **Logging**: Provides logging capabilities for plugins

### 2.3. **PreBus Validation Plugin** - Business Rules

**File**: `ValidateShipping.cs`

```csharp
public partial class ValidateShipping : FlexiBusinessRuleBase, IFlexiBusinessRule<AddToShippingDataPacket>
{
    public override string Id { get; set; } = "3a1cd0401f931dd4a01587e229b720dc";
    public override string FriendlyName { get; set; } = "ValidateShipping";

    protected readonly ILogger<ValidateShipping> _logger;
    protected readonly RepoFactory _repoFactory;

    public ValidateShipping(ILogger<ValidateShipping> logger, RepoFactory repoFactory)
    {
        _logger = logger;
        _repoFactory = repoFactory;
    }

    public virtual async Task Validate(AddToShippingDataPacket packet)
    {
        //Uncomment the below line if validating against a db data using your repo
        //_repoFactory.Init(packet.Dto);

        //If any validation fails, uncomment and use the below line of code to add error to the packet
        //packet.AddError("key", "ErrorMessage");

        await Task.CompletedTask; //If you have any await in the validation, remove this line
    }
}
```

**What Happens:**

* **Business Rule Validation**: Implements specific validation logic
* **Database Access**: Can access repository for data validation
* **Error Reporting**: Adds errors to the data packet if validation fails
* **Async Support**: Supports asynchronous validation operations
* **Dependency Injection**: Receives logger and repository factory

### 2.4. **PreBus Plugin Benefits**

* **Modular Validation**: Each plugin handles one validation concern
* **Reusable Rules**: Plugins can be reused across different features
* **Testable**: Each plugin can be unit tested independently
* **Configurable**: Plugins can be enabled/disabled per feature
* **Extensible**: Easy to add new validation rules
* **Ordered Execution**: Plugins execute in defined sequence

### 3. **Command Handler** - RESTClient Integration

**File**: `AddToShippingHandler.cs`

```csharp
public partial class AddToShippingHandler : IAddToShippingHandler
{
    protected string EventCondition = "";
    protected readonly ILogger<AddToShippingHandler> _logger;
    protected readonly IFlexHost _flexHost;
    protected ShippingRESTClient _restClient;
    protected FlexAppContextBridge? _flexAppContext;

    public AddToShippingHandler(ILogger<AddToShippingHandler> logger, IFlexHost flexHost, ShippingRESTClient restClient)
    {
        _logger = logger;
        _flexHost = flexHost;
        _restClient = restClient;
    }

    public virtual async Task Execute(AddToShippingCommand cmd, IFlexServiceBusContext serviceBusContext)
    {
        // Convert internal DTO to Request DTO
        AddToShippingRequestDto requestParams = new AddToShippingRequestDto
        {
            OrderId = cmd.Dto.OrderId,
            ShippingAddress = cmd.Dto.ShippingAddress,
            TrackingNumber = cmd.Dto.TrackingNumber,
            TotalWeight = cmd.Dto.ShippingItems?.Sum(x => x.Weight) ?? 0,
            ShippingItems = cmd.Dto.ShippingItems?.Select(x => new ShippingItemRequestDto
            {
                ProductId = x.ProductId,
                Quantity = x.Qty,
                Weight = x.Weight,
                Volume = x.Volume
            }).ToList()
        };

        // Call external REST service
        var response = await _restClient.AddToShipping(requestParams);

        // Process response
        if (response.IsSuccessStatusCode)
        {
            var responseContent = await response.Content.ReadAsStringAsync();
            var responseDto = JsonConvert.DeserializeObject<AddToShippingResponseDto>(responseContent);
            
            _logger.LogDebug("Shipping created successfully with external ID: {ExternalId}", responseDto?.Id);
            
            // Set success condition for event firing
            EventCondition = "CONDITION_ONSUCCESS";
        }
        else
        {
            _logger.LogError("Failed to create shipping. Status: {StatusCode}", response.StatusCode);
            EventCondition = "CONDITION_ONFAILED";
        }

        await this.Fire(EventCondition, serviceBusContext);
    }
}
```

**What Happens:**

* **DTO Mapping**: Converts internal DTO to Request DTO for external system
* **RESTClient Call**: Calls external shipping service via RESTClient
* **Response Processing**: Handles success/failure responses from external system
* **Logging**: Logs success/failure of external service call
* **Event Publishing**: Fires events based on external service result

### 4. **NServiceBus Handler** - Message Processing

**File**: `AddToShippingNsbHandler.cs`

```csharp
public class AddToShippingNsbHandler : NsbCommandHandler<AddToShippingCommand>
{
    readonly ILogger<AddToShippingNsbHandler> _logger;
    readonly IFlexHost _flexHost;
    readonly IAddToShippingHandler _handler;

    public AddToShippingNsbHandler(ILogger<AddToShippingNsbHandler> logger, IFlexHost flexHost, IAddToShippingHandler handler)
    {
        _logger = logger;
        _flexHost = flexHost;
        _handler = handler;
    }

    public override async Task Handle(AddToShippingCommand message, IMessageHandlerContext context)
    {
        _logger.LogTrace($"Executing {nameof(AddToShippingNsbHandler)}");

        await _handler.Execute(message, new NsbHandlerContextBridge(context));
    }
}
```

**What Happens:**

* **Message Reception**: Receives `AddToShippingCommand` from message bus
* **Logging**: Logs handler execution
* **Delegation**: Calls the actual command handler
* **Context Bridge**: Converts NServiceBus context to FlexBase context

### 6. **Event Publishing** - Asynchronous Processing

**Event**: `ShippingAddedEvent`

```csharp
public class ShippingAddedEvent : FlexEventBridge<FlexAppContextBridge>
{
    // Event data is automatically populated by FlexBase
}
```

**What Happens:**

* **Event Creation**: FlexBase creates event with shipping data
* **Message Bus**: Event is published to message bus
* **Subscriber Notification**: All subscribers are notified

### 7. **RESTClient Integration** - External Communication

**File**: `ShippingRESTClient_AddToShipping.cs`

```csharp
public async Task<HttpResponseMessage> AddToShipping(AddToShippingRequestDto model)
{
    var httpClient = _httpClientFactory.CreateClient(ShippingServicesRESTClientMaster.Name);

    var serializedModel = JsonConvert.SerializeObject(model);

    var request = new HttpRequestMessage(
           HttpMethod.Post,
           $"yourUri");
    request.Content = new StringContent(serializedModel, Encoding.UTF8, "application/json");
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

    return await response.HandleHttpResponse();
}
```

**What Happens:**

* **HTTP Client**: Creates HTTP client for external communication
* **Serialization**: Converts Request DTO to JSON
* **HTTP Request**: Sends POST to external shipping system
* **Response Handling**: Processes HTTP response from external system

### 7.1. **Request DTO** - External Contract

**File**: `AddToShippingRequestDto.cs`

```csharp
public partial class AddToShippingRequestDto
{
    public string OrderId { get; set; }
    public string ShippingAddress { get; set; }
    public string TrackingNumber { get; set; }
    public decimal TotalWeight { get; set; }
    public ICollection<ShippingItemRequestDto> ShippingItems { get; set; }
}
```

**What Happens:**

* **External Contract**: Designed for external system consumption
* **Serialization**: Optimized for JSON serialization
* **Validation**: May include external system specific validation

### 7.2. **Response DTO** - External Contract

**File**: `AddToShippingResponseDto.cs`

```csharp
public partial class AddToShippingResponseDto
{
    public string Id { get; set; }
    public string Status { get; set; }
    public string Message { get; set; }
    public DateTime ProcessedDate { get; set; }
    public string ExternalReferenceId { get; set; }
}
```

**What Happens:**

* **External Contract**: Designed for external system responses
* **Deserialization**: Optimized for JSON deserialization
* **External Fields**: May include external system specific fields

### 7.3. **Mapping Configuration** - DTO Transformation

**File**: `ShippingRESTClientMapperProfile.cs`

```csharp
public class ShippingRESTClientMapperProfile : Profile
{
    public ShippingRESTClientMapperProfile()
    {
        // Internal DTO → Request DTO Mapping
        CreateMap<AddToShippingDto, AddToShippingRequestDto>()
            .ForMember(d => d.TotalWeight, opt => opt.MapFrom(s => s.ShippingItems.Sum(x => x.Weight)))
            .ForMember(d => d.ShippingItems, opt => opt.MapFrom(s => s.ShippingItems));
            
        // Response DTO → Internal DTO Mapping
        CreateMap<AddToShippingResponseDto, AddToShippingDto>()
            .ForMember(d => d.Status, opt => opt.MapFrom(s => ParseStatus(s.Status)))
            .ForMember(d => d.ExternalReferenceId, opt => opt.MapFrom(s => s.ExternalReferenceId));
    }
    
    private ShippingStatus ParseStatus(string status)
    {
        return status?.ToLower() switch
        {
            "created" => ShippingStatus.Created,
            "in_transit" => ShippingStatus.InTransit,
            "delivered" => ShippingStatus.Delivered,
            "cancelled" => ShippingStatus.Cancelled,
            _ => ShippingStatus.Unknown
        };
    }
}
```

**What Happens:**

* **Request Mapping**: Converts internal DTO to external request format
* **Response Mapping**: Converts external response to internal DTO format
* **Field Transformation**: Handles different field names and types
* **Business Logic**: Applies business rules during mapping

### 8. **Event Subscribers** - Side Effects

**File**: `NotifyLogisticsOnShippingAdded.cs`

```csharp
public partial class NotifyLogisticsOnShippingAdded : INotifyLogisticsOnShippingAdded
{
    protected readonly ILogger<NotifyLogisticsOnShippingAdded> _logger;
    protected string EventCondition = "";

    public NotifyLogisticsOnShippingAdded(ILogger<NotifyLogisticsOnShippingAdded> logger)
    {
        _logger = logger;
    }

    public virtual async Task Execute(ShippingAddedEvent @event, IFlexServiceBusContext serviceBusContext)
    {
        _flexAppContext = @event.AppContext;

        //TODO: Write your business logic here:
        // - Send shipping confirmation email
        // - Update inventory levels
        // - Notify logistics system
        // - Update tracking information

        await this.Fire<NotifyLogisticsOnShippingAdded>(EventCondition, serviceBusContext);
    }
}
```

**What Happens:**

* **Event Reception**: Receives `ShippingAddedEvent` from message bus
* **Side Effects**: Executes business logic (emails, notifications, etc.)
* **Additional Events**: Can fire more events if needed

## Data Transfer Objects (DTOs)

### **Internal DTOs** - Application Contracts

#### **Input DTO**: `AddToShippingDto`

```csharp
public partial class AddToShippingDto : DtoBridge 
{
    [StringLength(100)]
    public string OrderId { get; set; }

    [StringLength(200)]
    public string ShippingAddress { get; set; }

    public ICollection<AddToShippingDto_ShippingItem> ShippingItems { get; set; }
}
```

#### **Command**: `AddToShippingCommand`

```csharp
public class AddToShippingCommand : FlexCommandBridge<AddToShippingDto, FlexAppContextBridge>
{
    // Command data is automatically populated by FlexBase
}
```

### **External DTOs** - External System Contracts

#### **Request DTO**: `AddToShippingRequestDto`

```csharp
public partial class AddToShippingRequestDto
{
    public string OrderId { get; set; }
    public string ShippingAddress { get; set; }
    public string TrackingNumber { get; set; }
    public decimal TotalWeight { get; set; }
    public ICollection<ShippingItemRequestDto> ShippingItems { get; set; }
}
```

#### **Response DTO**: `AddToShippingResponseDto`

```csharp
public partial class AddToShippingResponseDto
{
    public string Id { get; set; }
    public string Status { get; set; }
    public string Message { get; set; }
    public DateTime ProcessedDate { get; set; }
    public string ExternalReferenceId { get; set; }
}
```

### **DTO Mapping Relationships**

```
Internal DTO (AddToShippingDto) ←→ Request DTO (AddToShippingRequestDto)
     ↑                                    ↓
     │                              External System
     │                                    ↓
     └── Response DTO (AddToShippingResponseDto) ←┘
```

## Flow Summary

### **Synchronous Flow (Immediate Response)**

1. **POST Request** → Controller receives request
2. **Service Processing** → Business orchestration and PreBus validation
3. **PreBus Plugins** → Sequential validation of business rules
4. **Command Handler** → RESTClient integration
   * Internal DTO → Request DTO mapping
   * External system API call
   * Response DTO processing
5. **Response** → HTTP 201 with shipping ID

### **Asynchronous Flow (Event Processing)**

1. **Event Publishing** → ShippingAddedEvent published to message bus
2. **Subscriber Processing** → NotifyLogisticsOnShippingAdded executes
3. **Side Effects** → Emails, notifications, inventory updates
4. **Additional Events** → Can trigger more business processes

### **External Communication Flow**

1. **Internal DTO** → Request DTO mapping
2. **RESTClient Call** → HTTP request to external system
3. **External Response** → Response DTO from external system
4. **Response Mapping** → Response DTO to Internal DTO
5. **Data Integration** → External data integrated with internal data

## Key Benefits

* **Separation of Concerns**: Each layer has a single responsibility
* **Testability**: Each component can be tested independently
* **Scalability**: Asynchronous processing handles high loads
* **Maintainability**: Clear, readable code structure
* **Event-Driven**: Loose coupling between components

***

**This AddToShipping example demonstrates how FlexBase enables clean, maintainable, and scalable insert operations with proper separation of concerns and event-driven architecture!** 🚀
