Pattern: Version Identifier

How can an API provider indicate its current capabilities as well as the existence of possibly incompatible changes to clients in order to prevent malfunctioning of clients due to undiscovered interpretation errors?


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

Pattern: Version Identifier

a.k.a. Explicit Versioning, Message-Level Version Information

Context

An API that runs in production evolves. New versions with improved functionality are offered over time. At some point in time, the changes of a new version are no longer backwards compatible; this caused existing clients to break.

Problem

How can an API provider indicate its current capabilities as well as the existence of possibly incompatible changes in order to prevent malfunctioning of API clients due to undiscovered interpretation errors?

Forces

  • Accuracy and exact identification of API version
  • Guaranteeing that API changes do not lead to accidentally breaking compability between client and provider on the semantic level
  • Minimizing impact on the client side caused by API changes
  • Traceability of API versions in use for governance

Pattern forces are explained in depth in the book.

Solution

Introduce an explicit version indicator. Include this Version Identifier in the API Description and in the exchanged messages. To do the latter, add a Metadata Element to the endpoint address, the protocol header, or the message payload.

Example

In REST APIs the version of different features can be indicated as follows. The version of specific representation formats supported by the client in the content type negotiation headers of HTTP:

GET /customers/1234
Accept: text/json+customer; version=1.0
...

The version of specific operations is found as part of the resource identifiers:

GET v2/customers/1234
...

The version of the whole API can also be specified in the host domain name:

GET /customers/1234
Host: v2.api.service.com
...

In SOAP/XML-based APIs, the version is usually indicated as part of the namespace of the top-level message element:

<soap:Envelope>
  <soap:Body>
    <ns:MyMessage xmlns:ns="http://www.nnn.org/ns/1.0/">
    ...
    </ns:MyMessage>
  </soap:Body>
</soap:Envelope>

Another possibility is to specify the version in the payload as in the following JSON example. In the initial version 1.0 of the billing API, the prices were defined in Euro:

{
  "version": "1.0",
  "products": [
    {
      "productId": "ABC123",
      "quantity": 5;
      "price": 5.00;
    }
  ]
}

With a new version the requirement of multi-currency was realized. This leads to the new data structure and the new contents of the version element:

{
  "version": "2.0",
  "products": [
   {
      "productId": "ABC123",
      "quantity": 5;
      "price": 5.00;
      "currency": "USD"
   }
  ]
}

If no Version Identifier or any other mechanism to indicate a breaking change had been used, old software interpreting the version 2.0 of the message would assume that the product costs 5 EUR although it costs 5 USD. This is because a new attribute has changed the semantics of an existing one. Passing the version in the content type as shown above can eliminate this problem. While it would be possible to introduce a new field priceWithCurrency to avoid this problem, such changes lead to technical debt by aggregating over time, especially in less trivial examples.

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

This pattern has many known uses, both public ones and company- or community-internal ones:

  • Most public Web APIs use a simple, unstructured Version Identifier in the request URI, and many of them add it to response headers as well. One number often is sufficient. The Facebook Graph API and the Twitter APIs use a n.m convention (two digits).
  • GitHub uses the HTTP Accept Header.
  • A large European bank places Version Identifiers on the operation level in its WSDL contracts and transmits them as part of the request and response messages.
  • The Dynamic Interface described in Brandner et al. (2004) applies the pattern, indicating version identifiers in the service names (i.e., WSDL port types).
  • The SOAP-based eCH APIs use XML namespaces to realize the pattern. An example of such namespace is: http://www.ech.ch/xmlns/eCH-0134/1. XML namespaces are commonly defined with URIs.

More Information

Related Patterns

A Version Identifier can be seen as a special type of Id Element and/or Metadata Element; “Enterprise Integration Patterns” Hohpe and Woolf (2003) also discuss more general patterns that are related. The Version Identifier can be further structured, e.g., by using the Semantic Versioning pattern. The lifecycle pattern Two in Production requires explicit versioning; the other life cycle patterns (Aggressive Obsolescence, Experimental Preview, Limited Lifetime Guarantee, Eternal Lifetime Guarantee) may also use it.

Applying the Tolerant Reader pattern from “Service Design Patterns” Daigneau (2011) allows clients to tolerate some changes.

The visibility and role of an API drive related design decisions. For instance, the different life cycles, deployment frequencies, and release dates of provider(s) and client(s) in a Public API scenario for Frontend Integration make it necessary to plan service evolution beforehand and usually do not allow providers to make arbitrary ad hoc changes to already published APIs due to the impact of such changes on clients (e.g., downtimes, test and migration effort caused). Some or all of these clients might not even be known. A Community API providing Backend Integration capabilities between a few stable communication parties that are maintained on the same release cycle (and share a common roadmap) might be able to employ more relaxed versioning tactics. Finally, a Solution-Internal API connecting a mobile app frontend with a single backend (Frontend Integration) owned, developed, and operated by the same agile team might fall back to an ad hoc, opportunistic approach that relies on frequent, automated unit/integration tests within a continuous integration and delivery practice.

Other Sources

Because versioning is an important aspect of API and service design, there is much discussion about it in different development communities. The strategies differ widely, and versioning strategies are passionately debated. Opinions reach from no explicit versioning at all (sometimes just called “versioning”) because an API should always be backwards-compatible to the different versioning strategies compared by M. Little. James Higginbotham describes the available options here.

Chapter 11 of “SOA in Practice” Josuttis (2007) introduces a service life cycle in the context of Service-Oriented Architecture (SOA) design; Chapter 12 discusses versioning.

Chapter 13 of “Build APIs you won’t hate” Sturgeon (2016) discusses seven options for versioning (with the Version Identifier in URLs being one of these options) and their advantages and disadvantages. It also gives implementation hints.

Chapter 15 of “SOA with REST” Erl et al. (2013) deals with Service Versioning for REST.

Schema versioning is introduced in a blog post from Snowplow “Introducing SchemaVer for semantic versioning of schemas”.

References

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.
Daigneau, Robert. 2011. Service Design Patterns: Fundamental Design Solutions for SOAP/WSDL and RESTful Web Services. Addison-Wesley.
Erl, Thomas, Benjamin Carlyle, Cesare Pautasso, and Raj Balasubramanian. 2013. SOA with REST - Principles, Patterns and Constraints for Building Enterprise Solutions with REST. Prentice Hall.
Evans, Eric. 2003. Domain-Driven Design: Tacking Complexity in the Heart of Software. Addison-Wesley.
Hohpe, Gregor, and Bobby Woolf. 2003. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley.
Joachim, Nils, Daniel Beimborn, and Tim Weitzel. 2013. “The Influence of SOA Governance Mechanisms on IT Flexibility and Service Reuse.” The Journal of Strategic Information Systems 22 (1): 86–101. https://doi.org/https://doi.org/10.1016/j.jsis.2012.10.003.
Josuttis, Nicolai. 2007. SOA in Practice: The Art of Distributed System Design. O’Reilly.
Sturgeon, Phil. 2016. Build APIs You Won’t Hate. LeanPub. https://leanpub.com/build-apis-you-wont-hate.