How we do API versioning

5 min read
by Guy Marriott
July 29, 2020

As more sites move to the Jamstack and web APIs become the backbone of modern web development, we’re focused on providing an eCommerce API that developers enjoy using. One of our goals is to provide maximum flexibility in our API, and ship features that free the developer, rather than restrict them to conditions imposed by the API.

But there's one major issue with flexibility and APIs - breaking changes.

How can we be flexible and reactive, ship changes and features that developers want, without breaking all the code that people have already written using our API?

Our answer; we ship versions regularly, and allow developers to choose what version of the API handles their request.

Using the API for the first time

Starting with our "initial version" (2020-02-01), the Chec API will now indicate the version of the API that was used to respond to your request:

$ curl https://api.chec.io/ -sD - | grep Chec-Version
   Chec-Version: 2020-07-29

The first time that you use your API key, the Chec API will save the current version of the API against the key, and that version will be used whenever you use that API key in the future. Developers that are new to the API don't have to worry about versioning at all!

Updating the version of the API

If you have an existing integration using an older version of our API, you should look to update to a new version. In most cases, the new version might not require any changes to your integration, as the breaking changes introduced affect an endpoint or functionality that your integration does not rely on. The Chec Dashboard provides a configuration option alongside the API keys for choosing the version of the API.

If your integration does require changes, it can be difficult to test your changes with newer versions of the API if you have to control the version from the dashboard, so we recommend requesting the API version in your request to the API by setting the Chec-Version header with a valid version:

    $ curl https://api.chec.io/ -sH "Chec-Version: 1970-01-01" | jq
    {
      "error": {
        "type": "precondition_failed",
        "message": "The given API version (\"1970-01-01\") is not a valid version of the API"
      },
      "status_code": 412
    }

Should I use the dashboard setting or request headers?

In general, using request headers is more predictable and easier to test and deploy. We recommend being explicit and using the request headers in all situations where it's possible.

Migrating to newer versions

We'll be keeping a changelog of all the changes that warrant a new version in our API documentation. The changelog should indicate parts of your integration that may need to be updated. As usual, if you need help or clarification on any changes, feel free to contact us for assistance!

What's a breaking change?

Breaking changes are easy to misunderstand. For those developers who have tried working on a codebase that follows Semantic Versioning (SemVer), you will probably be familiar with just how easy it is to break an API - sometimes unwittingly. We have a similar approach to SemVer here—we will release a new version of the API when we have made a change worth of a "major" release.

Examples of breaking changes:

  • Removing parts of an existing response
  • Renaming keys in an existing response
  • Adding required parameters to an existing request
  • Changing the names of parameters in an existing request

Examples of non-breaking changes:

  • Adding a new feature that introduces an new endpoint
  • Adding new keys to existing responses
  • Adding new optional parameters to requests

Why not have traditional versioning?

Traditional versioning usually involves releasing a new API at a new endpoint (usually the version is in the URL) with no backwards compatibility. In order to ease the burden on developers, often APIs with traditional versioning will deprecate parts of their API, and you end up with extra content in your response that's only relevant for the developer indicating how this is going to eventually be broken and replaced in the future.

Often APIs build up over time with more and more deprecations and weird idiosyncrasies that come out of API authors working hard to avoid API breakages. Deprecations in responses also become an unnecessary cost paid for by consumers in the form of network bandwidth— especially prevalent in eCommerce APIs where the consumer's web browser may be making many API calls for carts and checkouts.

Here at Commerce.js and Chec, we want to move quickly, and have our APIs clean and easy to consume. Having to code in backwards compatibility seems like a small price to pay for clean and coherent APIs. For those developers who like to keep integrations up to date with APIs it's an even easier experience with frequent, smaller updates, versus infrequent gigantic change-sets.

You may have noticed that the Chec API has a version within the URL: https://api.chec.io/v1. We have made the conscious decision to leave in the version number, as we're not ruling out that at some point we may release a change that we cannot provide backwards compatibility for.

What’s next?

Our goal with our new API versioning is to move quickly and create an API that developers love to use, with no compromise to an API that existing developers have already grown to love. We always want to avoid making breaking changes, but we hope this form of versioning means that when we do make breaking changes, developers keep the flexibility to integrate these changes at their own pace.

As always, feel free to get in touch and share your feedback!

You might also like