Pattern Sections
Pattern: Request Bundle
a.k.a. Request Batch, Request Deck, Bulk Request-Response
Context
An API endpoint that exposes one or more operations has been specified. The API provider observes that clients make many small requests; individual responses are returned for these requests. These chatty interaction sequences harm scalability and throughput.
Problem
How can the number of requests and responses be reduced to increase communication efficiency?
Forces
The following top-level forces have to be resolved by this pattern:
- Complexity of endpoint, client, and message payload design and programming
- Accuracy of reporting and billing
- Latency
- Throughput
Pattern forces are explained in depth in the book.
Solution
Define a Request Bundle as a data container that assembles multiple independent requests in a single request message. Add metadata such as identifiers of individual requests and bundle element counter.
Sketch
A solution sketch for this pattern from pre-book times is:
Example
In the Lakeside Mutual Customer-Core service1, clients can request multiple customers from the Customers Information Holder Resource by specifying an Atomic Parameter List of customer Id Elements:
curl http://localhost:8080/customers/ce4btlyluu,rgpp0wkpec
This will return the two requested customer Data Elements:
{
"customers" : [
{
"customerId" : "ce4btlyluu",
"firstname" : "Robbie",
"lastname" : "Davenhall",
"birthday" : "1961-08-11T23:00:00.000+0000",
...
"_links" : { ... }
},
{
"customerId" : "rgpp0wkpec",
"firstname" : "Max",
"lastname" : "Mustermann",
"birthday" : "1989-12-31T23:00:00.000+0000",
...
"_links" : { ... }
}
],
"_links" : { ... }
}
This example implements the pattern in the Request Bundle with Single Bundled Response way introduced above.
Are you missing implementation hints? Our papers publications provide them (for selected patterns).
Consequences
The resolution of pattern forces and other consequences are discussed in our book.
Known Uses
Usage of this pattern is quite common both in Public APIs and in Community APIs in enterprises; they also exist in Solution-Internal APIs:
- The Google
Calendar API has the notion of Batch Requests. A Batch
Request is implemented by sending a request with the
multipart/mixed
content type to a dedicated batch endpoint. The individual requests are each sent as a part of the body, separated by aContent-Type: application/http
header and an optionalContent-ID
Metadata Element. Because body parts inmultipart/mixed
requests can also have their own headers, the endpoint just needs to unpack the Request Bundle and can then handle the bundled requests as if they were sent individually. The response will also mirror the request structure, bundling up all responses and tagging them with the correspondingContent-ID
header. - The Adidas API Guidelines has a section on Batch Operations. In contrast to the Google Calendar API, Batch Operations are not implemented by leveraging HTTP and a separate batch endpoint but by sending a Parameter Forest instead of a single body Parameter Tree to the same endpoint.
- A large Swiss bank has described this pattern in their global service design guidelines for efficiently running large (batch-like) requests in their service-oriented architecture. By reducing the request count from a large n to one request only, many resources (network bandwidth, CPU usage for marshalling/unmarshalling etc.) can be saved. Offering such operations make only sense when a client specifically requires to operate on a list of business objects at once. The service guidelines also defined a custom Error Report in order to send back errors on the level of a business object and not on the level of the service call at a whole.
- This pattern is frequently used in batch processing (e.g., also in Terravis by Lübke and Lessen (2016)): Every line specifies a business operation to be executed individually from all other lines. The result is usually replied back to the client line by line where each line in the response file corresponds to a line in the request file. File processing might have been retired or forgotten in the (modern) mindsets of integration architects, but can be very efficient because it causes less serialization overhead than, for instance, highly repetitive XML or JSON structures.
- The Dynamic Interface described in Brandner et al. (2004) also applies this pattern. Multiple application-level service requests operating on the core banking domain model can be combined into one Web service invocation.
- SWITCH edu-ID, an identity management solution for Swiss universities, offers bulk requests to “check if a number of edu-ID accounts still exist”.
For further known uses, see the Batch/Bulk topic in the API Stylebook.
More Information
Related Patterns
The request and response messages of a Request Bundle form Parameter Forests and Parameter Trees. Additional information about the structure and information needed to identify individual requests are instances of the Metadata Element pattern. Identifier information might follow the Correlation Identifier pattern Hohpe and Woolf (2003) for correlating requests and their responses.
If the endpoint is an Information Holder Resource, the Wish List and Wish Template patterns might alternatively be used by the client to request multiple entities at once.
A Request Bundle can be combined with any of the patterns Conditional Request, Wish List, and Wish Template. But as all have similar positive impact on forces, it is must be carefully analyzed if enough gains can be realized in order to warrant the complexity of a combination of two or even three of those patterns.
Using a Request Bundle has a positive influence on a Rate Limit, as less data is transferred when the pattern is used.
Message Sequence in Hohpe and Woolf (2003) solves the opposite problem: to reduce the message size, messages are split into smaller ones and tagged with a sequence ID. The price for this is a higher number of messages.
Request Bundle can be seen as an extension of the general Command design pattern from Gamma et al. (1995): each individual request is a command according to terminology from Gamma et al. (1995).
Other Sources
Recipe 13 in Chapter 11 of the RESTful Web Services Cookbook by Allamaraju (2010) advises against providing a generalized endpoint to tunnel multiple individual requests. Instead, providers should offer endpoints that support the use case without generalizing the problem.
Coroutines can improve performance when applying the Request Bundle pattern in the context of batch processing (a.k.a. chunking). See this SSP 2019 paper for a deeper discussion Knoche (2019).
References
Lakeside Mutual is a fictitious insurance company invented by the authors comprising of several microservices to demonstrate the patterns in action. It can be found at https://github.com/Microservice-API-Patterns/LakesideMutual/blob/master/customer-core/src/main/java/com/lakesidemutual/customercore/interfaces/CustomerInformationHolder.java#L206.↩︎