Category Overview
The Structure Patterns category comprises the following patterns:
API contracts contain the unique address of one or more API endpoints (e.g., a URI in SOAP or RESTful HTTP) and the identifier of the operation (e.g., the service name of a SOAP Web service call or the name of a RESTful HTTP resource) plus the message structures (i.e., the request message and response message of the operation).
This category of our pattern language deals with such aspects of interface representation structure design. It addresses the following design issue:
What is an adequate number of API message parameters? How should these parameters be structured? How can they be grouped and annotated with usage instructions?
For instance, in a RESTful HTTP context this design issue can be interpreted as how the URI, form, and body parameters transported with the message are structured and how many parameters are transported. In a RESTful HTTP API usually the request body is used for data sent to or received from the server (e.g., in JSON, XML, or another MIME type), and the query parameters of the URL are used to specify the exact data requested.
In a WSDL/SOAP context, we can interpret this design issue as how the SOAP message parts should be organized and which data types should be used to define the corresponding elements in an XML schema.
The following Structure Patterns have been published so far:
Special Purpose Representations
|
Pattern: API Key
|
Problem |
How can an API provider identify and authenticate clients and their requests? |
Solution |
As an API provider, assign each client a unique token —- the API Key -— that the client can present to the API endpoint for identification purposes. |
|
Pattern: Error Report
|
Problem |
How can an API provider inform its clients about communication and processing faults? How can this information be made independent of the underlying communication technologies and platforms (for example, protocol-level headers representing status codes)? |
Solution |
Reply with error codes in response messages that indicate and classify the faults in a simple, machine-readable way. In addition, add textual descriptions of the errors for the API client stakeholders, including developers and/or end users such as administrators. |
|
Pattern: Context Representation
|
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 made visible to related subsequent ones in conversations?
|
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.
|
Representation Elements
|
Pattern: Atomic Parameter
|
Problem |
How can simple, unstructured data (such as a number, a string, a Boolean value, or a block of binary data) be exchanged between API client and API provider? |
Solution |
Define a single parameter or body element. Pick a basic type from the type system of the chosen message exchange format for it. If justified by receiver-side usage, identify this Atomic Parameter with a name. Document name (if present), type, cardinality, and optionality in the API Description. |
|
Pattern: Atomic Parameter List
|
Problem |
How can multiple related Atomic Parameters be combined in a representation element so that each of them stays simple, but their relatedness becomes explicit in the API Description and the runtime message exchanges? |
Solution |
Group two or more simple, unstructured data elements in a single cohesive representation element to define an Atomic Parameter List that contains multiple Atomic Parameters. Identify its items by position (index) or by a string-valued key. Identify the Atomic Parameter List as a whole with its own name as well if that is needed to process it in the receiver. Specify how many elements are required and permitted to appear. |
|
Pattern: Parameter Tree
|
Problem |
How can containment relationships be expressed when defining complex representation elements and exchanging such related elements at runtime? |
Solution |
Define a Parameter Tree as a hierarchical structure with a dedicated root node that has one or more child nodes. Each child node may be a single Atomic Parameter, an Atomic Parameter List, or another Parameter Tree, identified locally by a name and/or by position. Each node might have an exactly-one cardinality, but also a zero-or-one cardinality, an at-least-one cardinality, or a zero-or-more cardinality. |
|
Pattern: Parameter Forest
|
Problem |
How can multiple Parameter Trees be exposed as request or response payload of an API operation? |
Solution |
Define a Parameter Forest comprising two or more Parameter Trees. Locate the forest members by position or name. |
Element Stereotypes
|
Pattern: Data Element
|
Problem |
How can domain/application-level information be exchanged between API clients and API providers without exposing provider-internal data definitions in the API? How can API client and API provider be decoupled from a data management point of view?
|
Solution |
Define a dedicated vocabulary of Data Elements for request and response messages that wraps and/or maps the relevant parts of the data in the business logic of an API implementation.
|
|
Pattern: Metadata Element
|
Problem |
How can messages be enriched with additional information so that receivers can interpret the message content correctly, without having to hardcode assumptions about the data semantics?
|
Solution |
Introduce one or more Metadata Elements to explain and enhance the other representation elements that appear in request and response messages. Populate the values of the Metadata Elements thoroughly and consistently; process them as to steer interoperable, efficient message consumption and processing.
|
|
Pattern: Id Element
|
Problem |
How can API elements be distinguished from each other at design time and at runtime? When applying domain-driven design, how can elements of the Published Language be identified?
|
Solution |
Introduce a special type of Data Element, a unique Id Element, to identify API endpoints, operations, and message representation elements that have to be distinguished from each other. Use these Id Elements consistently throughout API Description and implementation. Decide whether an Id Element is globally unique or valid only within the context of a particular API.
|
|
Pattern: Link Element
|
Problem |
How can API endpoints and operations be referenced in request and response message payloads so that they can be called remotely?
|
Solution |
Include a special type of Id Element, a Link Element, to request or response messages. Let these Link Elements act as human- and machine-readable, network-accessible pointers to other endpoints and operations. Optionally, let additional Metadata Elements annotate and explain the nature of the relationship.
|
Earlier versions of a subset of these patterns are featured in our EuroPLoP 2017 paper Interface Representation Patterns: Crafting and Consuming Message-Based Remote APIs. A free PDF version of this paper can be downloaded here.