Learn how API versioning enables teams to make changes to their API without creating problems for consumers.
What is API versioning?
API versioning is the process of managing and tracking changes to an API. It also involves communicating those changes to the API's consumers.
Change is a natural part of API development. Sometimes, developers have to update their API's code to fix security vulnerabilities, while other changes introduce new features or functionality. Some changes do not affect consumers at all, while others, which are known as “breaking changes,” lead to backward-compatibility issues, such as unexpected errors and data corruption. API versioning ensures that these changes are rolled out successfully in order to preserve consumer trust while keeping the API secure, bug-free, and highly performant.
Here, we'll review the benefits of API versioning and discuss several scenarios in which it is necessary. We'll also explore some of the most common approaches to API versioning, provide five steps for successfully versioning an API, and highlight some best practices for API versioning. Finally, we'll discuss how the Postman API Platform can support your API versioning workflow.
What are the benefits of API versioning?
It's essential for an API's producers and consumers to stay in sync as the API evolves—regardless of whether it is private or public. An effective API versioning strategy not only enables API producers to iterate in a way that minimizes the consumer-facing impact of breaking changes, but also provides a framework for effectively communicating these changes to consumers. This transparency builds trust and—in the case of public APIs—strengthens the organization's reputation, which can boost the API's adoption and retention rates.
When should you version an API?
You should version your API whenever you make a change that will require consumers to modify their codebase in order to continue using the API. This type of change is known as a “breaking change,” and it can be made to an API's input and output data structures, success and error feedback, and security mechanisms. Some common examples of breaking changes include:
- Renaming a property or endpoint: You might sometimes want to rename a property or method so that its meaning is clearer. While clear naming is important from an API design standpoint, it's almost impossible to change property or method names once the API is in production without breaking your consumers' code.
- Turning an optional parameter into a required parameter: As your API evolves, you may notice instances in which a certain input parameter should be mandatory, even though it was initially designed to be optional. While this type of change may help standardize inputs and make API operations more predictable, it will result in missing property errors for clients that are not programmed to pass a value for this property.
- Modifying a data format or type: You may sometimes realize that several properties, such as
lastName, should instead exist within a
userobject, instead of as separate properties that take string values. While this type of change would improve your API's design, it is nevertheless a breaking change that will cause a parsing exception.
- Modifying a property's characteristics: You may occasionally be tempted to change the rules for certain properties. For instance, a
type: stringmay have a
maxLengthrule that you discover is too low or too high. This type of change will have different results depending on its implementation, including database and UI errors.
What are some types of API versioning?
There are several approaches to API versioning, including:
- URL versioning: With this approach, the version number is included in the URL of the API endpoint. For instance, consumers who are interested in viewing all of the products in a database would send a request to the
https://example-api.com/v1/productsendpoint. This is the most popular type of API versioning.
- Query parameter versioning: This strategy requires users to include the version number as a query parameter in the API request. For instance, they might send a request to
- Header versioning: This approach allows consumers to pass the version number as a header in the API request, which decouples the API version from the URL structure.
- Consumer-based versioning: This versioning strategy allows consumers to choose the appropriate version based on their needs. With this approach, the version that exists at the time of the consumer's first call is stored with the consumer's information. Every future call is then executed against this same version—unless the consumer explicitly modifies their configuration.
It's important to note that these versioning strategies are used in tandem with a versioning scheme, such as semantic versioning or date-based versioning. Semantic versioning follows a three-part number format (i.e., 3.2.1), in which the first number represents a major update that might include breaking changes, the second number represents an update that includes new, backward-compatible features, and the third number represents bug fixes or patches. Date-based versioning, in contrast, identifies versions with the specific date on which they were released.
How do you version an API?
API versioning directly affects the overall success of an API, and it requires careful planning to ensure it is executed in a methodical way. API producers should follow these steps to version their API as effectively as possible:
Step 1: Choose a versioning strategy
It's important to choose an API versioning strategy during the API design phase of the API lifecycle. This versioning strategy should be shared across all APIs in your portfolio. The earlier you think about versioning, the more likely you are to choose resilient design patterns that will reduce the occurrence of breaking changes. An early decision about API versioning will also help your team align on a realistic roadmap for how your APIs will evolve to meet consumer needs for years to come.
Step 2: Confirm whether a new version is necessary
Change is an inevitable part of API development, but not every change necessitates a new version. Before deciding to roll out a new version, teams should assess the scope and impact of the change they want to make—and determine if there is a way to make it in a backward-compatible way. For instance, you may opt to add a new operation instead of modifying an existing one. If there's no way to avoid a breaking change, you might consider waiting to introduce it until you release an exciting new feature that will improve your consumers' experience.
Step 3: Update the documentation
If you've decided that it's time to version your API, it's important to update the API documentation to include information about the release. For instance, you'll want to communicate the reasoning behind the changes, how they will impact consumers, and how the new version can be accessed. You may also want to include a release timeline and migration instructions—especially if you plan to eventually deprecate the old version.
Step 4: Gradually deploy the new version
Whenever possible, teams should release a new API version in phases, starting with a small group of users. They should then gather feedback from these users and address any issues before releasing the new version more broadly. This approach helps teams verify that the new version works as expected—and provides valuable insight into how real consumers interact with the API.
Step 5: Deprecate the old version
Once the new version is stable, teams should monitor adoption in order to assess how many users have successfully migrated. If adoption rates are on track with expectations, teams can then create and announce a timeline for deprecating the old version. At this point, it's important to offer support to users who have continued to use the old version, as they may need help transitioning to the new version.
What are some best practices for API versioning?
A haphazard approach to API versioning can lead to negative consequences for an API's consumers and producers. The following best practices will help you avoid potential pitfalls and ensure the success of your API versioning strategy:
- Design with extensibility in mind: It's important to think strategically about versioning during the API design process. For instance, certain data types, such as booleans and arrays of atomics, are more vulnerable to breaking changes than others, so it's best to omit them from your API design when possible.
- Know your consumers: It's important to understand how your consumers are using your API when you're deciding whether to make changes. This involves being aware of the invisible API contract, which refers to unexpected implementations of your API. For example, consumers may access a property in an object by its index, rather than its property name. While this implementation was not intended by the API's producers, it should nevertheless be accounted for during the versioning process.
- Include a versioning policy in your terms of service: It's important to let your consumers know how you'll define a breaking change, when you'll warn them about upcoming changes, and how long they'll have to migrate to a new version. This practice is crucial for partner and public APIs—especially those that are monetized.
- Decouple implementation versioning and contract versioning: When it comes to versioning, it's important to consider the API's implementation separately from its contract. For instance, if you rewrite a Node.js implementation in Rust, but the contract doesn't change, you should not release a new version of the API.
- Test thoroughly: Versioning is a major event in an API's lifecycle, so it's important to do everything you can to ensure it goes smoothly. Thorough testing during development and deployment helps confirm that the new version works as expected—without introducing any new issues for consumers.
- Plan for deprecation: When developing a new version of an API, it's important to consider how and when you'll deprecate the old version. This involves establishing a deprecation policy, communicating the deprecation plan to consumers, monitoring usage of the old version as the deprecation date approaches, and finally, removing its servers and documentation. Careful deprecation planning and communication reduces the risk of surprises, keeps old instances from running for too long, and ensures consumers have enough time to transition to the new version.
How can Postman help with API versioning?
The Postman API Platform, which has been recognized by Gartner® as a Visionary in the Full Lifecycle API Management category for two years in a row, includes several features that enable teams to safely make changes to their API. With Postman, you can:
- Leverage built-in integrations with version control platforms: Postman enables you to connect to remote repositories on GitHub, Bitbucket, GitLab, or Azure DevOps. Once your API is connected to a repository, you can use Git-based version control to switch branches and pull or push changes without leaving Postman.
- Safely collaborate on Postman artifacts: Postman includes built-in version control features for working with Postman Collections, environments, and Postman Flows. For instance, team members can fork these entities and create pull requests without having the Editor role, which supports safe iteration and effective collaboration.
- Easily create public documentation: Postman makes it easy to publish public documentation, which automatically includes details for each request and endpoint, as well as code samples in various client languages. This documentation will also update automatically, so you don't have to worry about it falling out of sync with your collection.
- Leverage manual and automated testing features: Postman includes a robust set of API testing features that can help you validate the functionality of a new API version. For instance, teams can use Postman's Collection Runner to chain requests together and log test results, or they can leverage Newman or the Postman CLI to run tests against new API versions from within their CI/CD pipeline.