In this lesson, you will learn how to design API endpoints that efficiently handle the ingestion and processing of large collections of data in a single HTTP request.
When a client needs to send hundreds or thousands of entities—such as importing a list of products or logging sensor readings—sending them individually creates significant network overhead and database pressure. Instead, we use a "Bulk Endpoint" pattern.
Designing the Bulk Request
The most efficient approach is to accept a collection in a single POST or PUT request. By defining a specific DTO (Data Transfer Object) for the batch, you can use Fluent Validation (concept 4) to ensure the entire collection is structurally sound before processing begins.
[HttpPost("bulk")]
public async Task<IActionResult> ProcessBatch([FromBody] List<ProductDto> products)
{
// Pass the collection to a MediatR command for processing
var result = await _mediator.Send(new BulkProductCommand(products));
return Ok(result);
}
Efficiency Strategies
To keep these endpoints responsive, follow these three design rules:
- Asynchronous Processing: Since processing a massive batch might take longer than a standard HTTP timeout, consider returning a
202 Acceptedstatus code. You can then trigger an asynchronous background task (leveraging yourMediatRpattern, concept 22) and provide the client with aLocationheader to poll for status. - Database Batching: Avoid calling
SaveChangesAsync()inside a loop. Instead, use yourRepository(concept 23) to perform a bulk insert or update, which minimizes round-trips to the database engine. - Atomicity and Idempotency: If the batch fails halfway, do you want a partial success or a total rollback? Use a
Unit of Work(concept 23) to wrap the operation in a transaction. To prevent duplicate imports if a network error occurs during a retry, ensure your endpoint is idempotent (concept 25) by checking for existing unique identifiers within the batch.
By treating the collection as a single unit of work rather than a series of individual requests, you significantly reduce the pressure on your web server and database, keeping your API performant and resilient.
Key Takeaway: Bulk processing endpoints should leverage transaction management and asynchronous execution to transform high-volume data ingestion into a reliable, single-request operation.