Appendix B. Managing an API’s life cycle

APIs are very rarely static. As your product evolves, you need to expose new capabilities and features through your API, and this means that you will need to create new endpoints or change your schemas to introduce new entities or fields. Often, API changes are backward incompatible, which means clients who are unaware of the new changes will get failed responses to their requests. Part of managing an API is making sure that any changes you make don’t break the integrations that already exist with other applications, and API versioning serves that purpose. In this appendix, we study API versioning strategies to manage API changes.

In addition to evolving and changing, APIs also sometimes come to an end. Perhaps you’re migrating a REST API to GraphQL, or you’re ceasing a product altogether. If you’re planning to deprecate an API, you must let your clients know when and how it’ll happen, and in the second part of this appendix, you’ll learn to broadcast this information to your users.

B.1 Versioning strategies for evolving APIs

Let’s see how we use versioning to manage API changes. We use two major types of versioning systems for APIs:

  • Semantic versioning (SemVer, https://semver.org/)—This is the most common type of versioning, and it is widely used to manage software releases. It has the following format: MAJOR.MINOR.PATCH, for example, 1.1.0. The first number indicates the major version of the release, the second number indicates the minor version, and the third number indicates the patch version.

    The major version changes whenever you make a breaking change to the API, for example, when a new field is required in a request payload. Minor versions represent nonbreaking changes to the API, such as the introduction of a new optional query parameter. Your API consumers expect to be able to keep calling your endpoints in the same way on different minor versions and continue to obtain responses. Patch versions indicate bug fixes.

    In the context of APIs, we typically only use the major version, so we may have v1 and v2 of an API. Minor changes and patches that improve the API can generally be rolled out without the risk of breaking existing integrations.

  • Calendar versioning (CalVer, https://calver.org/)—Calendar versioning uses calendar dates to version releases. This system is useful when your APIs change very often, or when your releases are time sensitive. An increasing number of software products use calendar versioning, including Ubuntu (https://ubuntu.com/). AWS also uses calendar versioning in some of its products, such as CloudFormation (http://mng.bz/epQZ) and the S3 API (http://mng.bz/p6B0).

    CalVer does not provide a full specification about how to format your versions; it only emphasizes the use of dates. Some projects use the format YYYY.MM.DD, while others use YY.MM. If you make several releases per day, you can use an additional counter to keep track of each release, for example, 2022.12.01.3, which means this is the third release made on the 12th of December in 2022. (For more details on calendar versioning, see http://mng.bz/O6MO.)

Which type of versioning system is better? It depends on your specific needs and your overall API management strategy. SemVer is more commonly used since it’s more intuitive. However, if your product rollouts are time sensitive, CalVer is a better fit. Your choice of versioning system will also be affected by your versioning management strategy, so let’s take a look at the different methods we use to indicate the version of our APIs:

  • Versioning using the URL—You can embed the API version in the URL, for example, https://coffeemesh.com/api/v1/coffee. This is very convenient because consumers of your API know that they will always be able to call the same endpoint and get the same results. If you release a new version of your API, that version will go into a different URL path (/api/v2) and therefore will not conflict with your previous releases. It also makes your API easier to explore, since, to discover and test different versions of it, API consumers only need to change the version field in the URL. On the downside, when working with REST APIs, using the URL to manage versions is considered a violation of the principles of REST since every resource should be represented by one and only one URI.

  • Versioning using the Accept Header field—An API consumer uses the Accept HTTP request Header field to advertise the type of content they can parse. In the context of APIs, the typical value of the Accept Header is application/json, which means the client only accepts data in JSON format. Since the API version also influences the type of content we receive from the server, we can use the Header field to advertise which API version we want to use. An example of a Header field that specifies the content type and API version is Accept: application/json;v1.

    This approach is more harmonious with the principles of REST since it does not modify the resource endpoints, but it requires careful parsing. Introducing additional characters in the header’s value, as in the following snippet, can cause errors at runtime:

    Accept: application/json; v1  # note the additional space after the 
     semicolon

    Since we’re using the Accept header, we respond with a 415 (Unsupported Media Type) to any errors in the API version declaration, or when the client requests an unavailable version of the API.

  • Versioning using custom Request Header fields—In this approach, you use a custom Request Header field such as Accept-version to specify the version of the API you want to use. This approach is the least preferred, since some frameworks may not accept nonstandard Header fields, thus leading to integration issues with your clients.

Each versioning strategy comes with its own benefits and challenges. URL versioning is the most adopted strategy since it’s intuitive and easy to use. However, indicating the API version in the URL also means that our resource URIs change depending on the version of the API, which may be confusing for some clients.

Using the Accept header is another popular option, but it couples the logic for handling our media types with the logic for handling our API versions. Also, using the same error status code for both media types and API versions may be confusing for our API clients. The best strategy is to carefully consider the needs of our application and to agree with your API clients on the most preferred solution.

B.2 Managing the life cycle of your APIs

In this section, we study strategies to gracefully deprecate our APIs. APIs don’t last forever; as the products and services that you offer through APIs evolve and change, some of your APIs will become deprecated, and you will eventually retire them. However, you may have external consumers whose systems depend on your APIs, so you cannot just take them down without causing disruption to your clients. You must orchestrate your API deprecation process, and as you’ll see, we use specific HTTP headers to give notice of API deprecation. Let’s see how that works!

Before you retire an API, you should deprecate it first. A deprecated API is still in service, but it lacks maintenance, enhancements, and fixes. Once you deprecate your APIs, your users won’t expect further changes to them. Deprecation serves as a grace period for your users to give them time to migrate their systems to a new API without disrupting their operations.

As soon as you decide to deprecate your API, you should announce it to your API consumers through a standard communication channel, such as by email or in a newsletter. At the same time, you should set the Deprecation header in your responses.1 If the API is going to be deprecated in the future, we set the Deprecation header to the date when the API will be deprecated:

Deprecation: Friday, 22nd March 2025 23:59:59 GMT

Once the API is deprecated, we set the Deprecation header to true:

Deprecation: true

You can also use the Link header to provide additional information about your API deprecation process. For example, you can provide a link to your deprecation policy:

Link: <https://coffeemesh.com/deprecation>; rel=”deprecation”; 
 type=”text/html”

In this case, we are telling the user that they can follow the link https://coffeemesh.com/deprecation to find additional information about the deprecation of the API.

If you’re deprecating an old version of your API, you can use the Link header to provide the URL that replaces or supersedes the current API version:

Link: <https://coffeemesh.com/v2.0.0/coffee>; rel=”successor-version”

In addition to broadcasting the deprecation of your APIs, you should also announce when the API will be retired. We use the Sunset header to signal when the API will be retired:2

Sunset: Friday, 22nd June 2025 23:59:59 GMT

The date of the Sunset header must be later or the same as the date given in the Deprecation header. Once you’ve retired an API, you must let your API clients know that the old endpoints are no longer available. You may use any combination of 3xx and 4xx status codes when a user calls the old API. A good option is the 410 (Gone) status code. We use the 410 status code to signal that the requested resource no longer exists for a known reason. In some circumstances, 301 (Moved Permanently) might be useful. We use the 301 status code to signal that the requested resource has been assigned a new URI, and therefore it may be useful when you migrate your API to a new endpoint.

Proper management of API changes and deprecations is a crucial yet often overlooked ingredient necessary to deliver high-quality and reliable API integrations. By applying the recommendations from this appendix, you’ll be able to evolve your APIs with confidence and without breaking integrations with your clients.


1 Sanjay Dalal and Erik Wilde, “The Deprecation HTTP Header Field,” https://datatracker.ietf.org/doc/html/draft-ietf-httpapi-deprecation-header-02.

2 Erik Wilde, “The Sunset HTTP Header Field,” RFC 8594, https://tools.ietf.org/html/rfc8594.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset