Pattern: Context Representation

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 made visible to related subsequent ones in conversations?


The final version of this pattern is featured in our book Patterns for API Design: Simplifying Integration with Loosely Coupled Message Exchanges.

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

Allamaraju, Subbu. 2010. RESTful Web Services Cookbook. O’Reilly.
Alur, Deepak, Dan Malks, and John Crupi. 2013. Core J2ee Patterns: Best Practices and Design Strategies. 2nd ed. Prentice Hall.
Brandner, Michael, Michael Craes, Frank Oellermann, and Olaf Zimmermann. 2004. “Web Services-Oriented Architecture in Production in the Finance Industry.” Informatik-Spektrum 27 (2): 136–45. https://doi.org/10.1007/s00287-004-0380-2.
Cisco Systems. 2015. “API Design Guide.” 2015. https://github.com/CiscoDevNet/api-design-guide.
Hohpe, Gregor, and Bobby Woolf. 2003. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley.
Larman, Craig. 2004. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition). Prentice Hall.
Lübke, Daniel, and Tammo van Lessen. 2016. “Modeling Test Cases in BPMN for Behavior-Driven Development.” IEEE Software 33 (5): 15–21. https://doi.org/10.1109/MS.2016.117.
Martin, Robert C. 2008. Clean Code: A Handbook of Agile Software Craftsmanship. 1st ed. Prentice Hall.
Richardson, Chris. 2016. “Microservice Architecture.” http://microservices.io.
Schumacher, Markus, Eduardo Fernandez-Buglioni, Duane Hybertson, Frank Buschmann, and Peter Sommerlad. 2006. Security Patterns: Integrating Security and Systems Engineering. Wiley.
Stalnaker, Robert. 1996. “On the Representation of Context.” In Semantics and Linguistic Theory, 6:279–94.
Voelter, Markus, Michael Kircher, and Uwe Zdun. 2004. Remoting Patterns - Foundations of Enterprise, Internet, and Realtime Distributed Object Middleware. Wiley.


  1. Notation: Microservice Domain-Specific Language (MDSL). ↩︎