Quantcast
Channel: ASP.NET MVC / Web API / Web Pages
Viewing all articles
Browse latest Browse all 7925

Updated Wiki: Web API Request Batching

$
0
0

Overview

Request batching is a useful way of minimizing the number of messages that are passed between the client and the server. This reduces network traffic and provides a smoother, less chatty user interface. This feature will enable Web API users to submit multiple service calls in a single HTTP request.

Design

BatchHandler

This is a custom HttpMessageHandler that will be used to handle the batch requests.The BatchHandler takes two arguments in the constructor: an HttpServer and an IBatchProcessor.

  • HttpServer will be used to process the individual batch requests.
  • IBatchProcessor will be used to parse the request into individual batch requests and submit them to the HttpServer.
namespace System.Web.Http.Batch
{
    publicclass BatchHandler : HttpMessageHandler
    {
        public BatchHandler(HttpServer httpServer, IBatchProcessor batchProcessor);

        public IBatchProcessor BatchProcessor { get; }

        protectedoverride Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);
    }
}

IBatchProcessor

This is an abstraction for processing the batch requests.

namespace System.Web.Http.Batch
{
    publicinterface IBatchProcessor
    {
        Task<HttpResponseMessage> ExecuteAsync(HttpRequestMessage request, HttpMessageInvoker invoker, CancellationToken cancellationToken);
    }
}

An implementation of IBatchProcessor will do the following:

  • Parse the incoming request into batch requests
  • Execute the batch requests
  • Build the batch response

The idea is to have different IBatchProcessor implementations that understand different batch request/response formats and know how to process them.

Out of the box, we’re providing the DefaultBatchProcessor for Web API Batching

namespace System.Web.Http.Batch
{
    publicclass DefaultBatchProcessor : IBatchProcessor
    {
        publicbool OrderedExecution { get; set; }

        publicvirtual HttpResponseMessage CreateResponseMessage(IList<HttpResponseMessage> responses, HttpRequestMessage request);
        publicvirtual Task<HttpResponseMessage> ExecuteAsync(HttpRequestMessage request, HttpMessageInvoker invoker, CancellationToken cancellationToken);
        publicvirtual Task<IList<HttpResponseMessage>> ExecuteRequestMessagesAsync(IEnumerable<HttpRequestMessage> requests, HttpMessageInvoker invoker, CancellationToken cancellationToken);
        publicvirtual Task<IList<HttpRequestMessage>> ParseBatchRequests(HttpRequestMessage request);
        protectedvirtualvoid ValidateRequest(HttpRequestMessage request);
    }
}

datajs client

OData.request({
    requestUri: "/odata/$batch",
    method: "POST",
    data: {
        __batchRequests: [
            { __changeRequests: [
                { requestUri: "/odata/Customers", method: "POST", data: customer }
            ] },
            { requestUri: "/odata/Customers", method: "GET" }
        ]
    }
}, function (data, response) {
    //success handler
}, function () {
    alert("request failed");
}, OData.batchHandler);

Scenarios

Web API Batching

Registering default batch endpoint

You can use MapBatchRoute, which is an HttpRouteCollection extension method, to create a batch endpoint.

config.Routes.MapBatchRoute("apiBatch", "api/batch", GlobalConfiguration.DefaultServer);

Under the hood it just uses MapHttpRoute.

config.Routes.MapHttpRoute("apiBatch", "api/batch", null, null, new BatchHandler(GlobalConfiguration.DefaultServer, new DefaultBatchProcessor()));

Ordered Execution

By default each individual batch request is executed asynchronously. Meaning there’s no guarantee that the first batch request will finish executing before kicking off the second one. So if you have a scenario where you want to get the results after all the posts, you can enable the OrderedExecution which will process the requests in order.

var batchProcessor = new DefaultBatchProcessor();
batchProcessor.OrderedExecution = true;
config.Routes.MapBatchRoute("apiBatch", "api/batch", new BatchHandler(GlobalConfiguration.DefaultServer, batchProcessor));

OData Batching

Registering OData batch endpoint

You can use MapODataBatchRoute, which is an HttpRouteCollection extension method, to create an OData batch endpoint.

config.Routes.MapODataBatchRoute("odataBatch", "odata/$batch", GlobalConfiguration.DefaultServer);

Under the hood it just uses MapHttpRoute.

config.Routes.MapHttpRoute("odataBatch", "odata/$batch", null, null, new BatchHandler(GlobalConfiguration.DefaultServer, new ODataBatchProcessor()));

Configuring Batch Quotas

Work in progress…

var odataBatchProcessor = new ODataBatchProcessor();
odataBatchProcessor.MessageQuotas.MaxOperationsPerChangeset = 10;
odataBatchProcessor.MessageQuotas.MaxPartsPerBatch = 50;
config.Routes.MapBatchRoute("odataBatch", "odata/$batch", new BatchHandler(GlobalConfiguration.DefaultServer, odataBatchProcessor));

Order of Execution

According to the OData spec, the operation/ChangeSet within a batch request is executed in ordered manner. Operations within the ChangeSet can be executed regardless of the order but our implementation will execute them in order for simplicity.

Transaction

Work in progress…

Custom Batching

Work in progress…


Viewing all articles
Browse latest Browse all 7925

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>