Pattern Sections
Pattern: Context Representation
a.k.a. Shared and Explicit Context, QoS Property Collection, Embedded Custom Header
Context
An API endpoint and its operations have been defined. Context information has to be exchanged between API client and provider. Examples of such context information are client location and other API user profile data, the preferences forming a Wish List, or Quality-of-Service (QoS) controls such as credentials used to authenticate, authorize, and bill clients. Such credentials may be API Keys or JSON Web Tokens (JWT) claims.
Interactions between API client and API provider might be part of conversations and consist of multiple related operation calls. API providers can also act as API clients that consume services provided by other APIs (in their implementations) to create operation call sequences. Some parts of the context information might be local to single operations; others might be shared and handed over from operation invocation to operation invocation in such conversations.
Problem
How can API consumers and providers exchange context information without relying on any particular remoting protocols? How can identity information and quality properties in a request be handed over to subsequent ones in conversations?
Forces
In this context, these desired qualities make the problem hard to solve:
- Interoperability and modifiability on the technology/technical level (including centralization and decentralization of context information)
- Dependency on evolving protocols
- Developer productivity (control versus convenience)
- Diversity of clients and their requirements
- End-to-end security (across services and protocols)
- Logging and auditing on business domain level (across invocations)
To promote protocol independence and a platform-independent design, the default headers and header extension capabilities available in the underlying communication protocol cannot not be used sometimes.
Pattern forces are explained in depth in the book.
Solution
Combine and group all Metadata Elements that carry the desired information into a custom representation element in request and/or response messages. Do not transport this single Context Representation in protocol headers, but place it in the message payload. Separate global from local context in a conversation by structuring the Context Representation accordingly. Position and mark the consolidated Context Representation element so that it is easy to find and distinguish from other Data Elements.
Sketch
A solution sketch for this pattern from pre-book times is:
Example
The following service contract sketch introduces a custom
Context Representation in the
payload of the request message of the getCustomerAttributes
operation (rather than a protocol header). The
Context Representation is tagged and
highlighted with a <<Context_Representation>>
stereotype and therefore easily recognizable in the response payload:1
API description ContextRepresentationExample
data type KeyValuePair P // not specified
data type CustomerDTO P // not specified
data type RequestContext {
"apiKey":ID<string>,
"sessionId":D<int>?,
"qosPropertiesThatShouldNotGoToProtocolHeader":KeyValuePair*}
endpoint type CustomerInformationHolderService
exposes
operation getCustomerAttributes
expecting payload {
<<Context_Representation>> {
"requestContextSharedByAllOperations": RequestContext,
<<Wish_List>>"desiredCustomerAttributes":ID<string>+
},
<<Data_Element>> "searchParameters":D<string>*
}
delivering payload {
<<Context_Representation>> {
<<Metadata_Element>> {
"billingInfo": D<int>,
"moreAnalytics":D},
<<Error_Report>> {
"errorCode":D<int>,
"errorMessage":D<string>}
}, {
<<Pagination>> {
"thisPageContent":CustomerDTO*,
"previousPage":ID?,
"nextPage":ID?}
}
}
When transformed into OpenAPI, the above example renders as YAML as
shown in the
Context
Representation Example. The request payload of
getCustomerAttributes
contains a second use of the pattern:
The SharedContext
contains an
API
Key as well as a session
Id
Element (to be created by the provider upon successful
authentication). Additional free-form headers can be added in the
key-value part of it.
Note that the example also features three additional patterns: Wish List, Error Report and Pagination.
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
Known uses for this pattern are hard to find in Public APIs, but quite common in Community APIs in enterprises (and also exist in Solution-Internal APIs):
- The Dynamic Interface to core banking services described in Brandner et al. (2004) realizes this pattern to achieve protocol-independence en route from client frontends implemented in different programming languages (both browser-based and rich clients) to the mainframe-based backend. Both HTTP and proprietary backend protocols are in use in this service-oriented integration architecture. Contetx information appears both in request and response messages.
- The header parameter structure/representation used in the process integration architecture at Terravis (Lübke and Lessen (2016)) also qualifies as a known use. All SOAP request messages contain a header that includes a unique message ID, a global business process identifier as well as authorization and authentication information, e.g., partner business identification, user, request and business case ID, and originating system.
- A large Swiss bank also uses a context “header” to transfer and propagate the entire context information for requests. This header includes a unique identifier for the originating request, authentication information (user and role), timestamps, and originating system information (which system originally handled the incoming request). Country information is passed on as well in order to implement compartmentalization requirements. For example, Swiss bank customers must only be accessible by Swiss bank employees.
- The JSON Web Tokens (JWT) technology, as proposed by RFC 7519, “encode claims to be transmitted as a JSON object that is used as the payload of a JSON Web Signature structure [..], enabling the claims to be digitally signed or integrity protected[..]”. The claims are Metadata Elements used to represent context information, e.g. roles or expiration dates, about the currently logged-in user and are encoded into a single Atomic Parameter.
- A Swiss software vendor specializing on the insurance industry defines Context Representation in its internal REST API Design Guidelines to create a library of message representation fragments. For instance, structures and semantics of query filters and sort operators for Retrieval Operations as well as the entries in Wish Lists are described; the fragments are foreseen to be used in multiple endpoints and operations across APIs. This promotes understandability and interoperability and can be seen as an application of the pattern beyond quality-of-service.
JMS headers are specific to the integration style of Messaging; a JMS message contains both headers (that have names and values) and payload and can therefore be seen as an instance of the pattern (when not being exchanged natively by a message broker that implements JMS).
As a counter example, the Rate Limit example in Lakeside Mutual does not follow this pattern, but returns the rate information in custom HTTP headers. Such approach requires less upfront design and implementation work, at the price of tying the endpoint to the underlying protocol.
More Information
Related Patterns
A Context Representation contains and bundles multiple Metadata Elements for a particular purpose (with specific semantics, context sharing). An Error Report can find its place in a Context Representation, for instance when reporting errors caused by a Request Bundle (because the required summary-details structure is difficult to model in protocol-level headers or status codes).
A similar pattern appears in several other pattern languages. For instance, the Context Object in Alur, Malks, and Crupi (2013) solves the problem of protocol-independent storage of state and system information in a Java programming context (rather than in a remoting context).
The Invocation Context pattern Voelter, Kircher, and Zdun (2004) describes a solution for bundling contextual information in an extensible invocation context of a distributed invocation. An Invocation Context is transferred between client and remote object with every remote invocation.
The Envelope Wrapper pattern in Hohpe and Woolf (2003) solves a similar problem, making certain parts of a message visible to the messaging infrastructure that is responsible for a particular hop/leg. Systems management patterns such as Wire Tap be used to implement the required auditing and logging.
Other Sources
Chapter 3 in the RESTful Web Services Cookbook by Allamaraju (2010) discusses an alternative approach based on entity headers (in the context of HTTP) in two of its recipes.
Slide 7 in “Dimensions of Successful Web API Design and Evolution: Context, Contracts, Components” defines the term context and reports on its meaning(s) in different contexts. Cambridge Dictionary defines it as “the situation within which something exists or happens, and that can help explain it”. Stalnaker (1996) gives a good overview of context representation in linguistics.
The Metadata Element pattern provides more pointers to related patterns and other background information.
References
Notation: Microservice Domain-Specific Language (MDSL). ↩︎