RESTful Node.js: A Structured Approach
  • Book Cover
  • About the Author
  • Links and Resources
  • Part I: The Why
    • Foreword
    • Preface
    • Chapter 1: Introduction
      • The Rise of REST and Distributed Systems
      • Problem #1: Structureless Design, Structureless REST
      • The Emergence of JavaScript and Node.js
      • Problem #2: Structureless JavaScript, Structureless Node.js
      • Behold, the Solution: A Structured Approach
      • Summary
  • Part 2: The Theory
    • Chapter 2: REST Origins
      • A Brief History of the Web and the Birth of REST
      • REST vs. HTTP
      • REST - The Abstract Web Architecture
      • HTTP - A Peak at REST's Concrete Implementation
      • What does it mean for an API to be RESTful?
      • Measuring "RESTfulness" with Richardson Maturity Model
      • Pragmatic REST vs Dogmatic REST
      • Summary
    • Chapter 3: RESTful API Design Guidelines and "Best Practices"
      • Theories vs. Principles vs. Guidelines
      • URI Design
      • Method Verbs
      • Status Codes
      • Representational Design
      • Metadata Design
      • Versioning Strategies
      • Security Considerations
      • Documentation
      • Case Study: GitHub
      • Summary
    • Chapter 4: Structured JavaScript Architecture
      • The Monstrous Monolith and Its Downfall
      • Layered/N-Tier Architecture: The Unpopular Proven Way
      • Microservices and Distributed Computing: A Popular Misdirection
      • Summary
    • Chapter 5: The 8 Step Recipe
      • Route Name (URI)
      • Input Request
      • Middleware
      • Validation
      • Domain
      • Events
      • Output Response
      • Test, Refactor, Document
      • Summary
  • Part 3: The Code
    • Chapter 6: Introduction to the Bookstore API
      • The Bookstore API Endpoint Specifications
      • API Design and Code Structure
      • Project Setup
      • Summary
    • Chapter 7: Retrieving Books from our API
      • Retrieving All Books - Planning
      • Retrieving All Books - Implementation
      • Retrieving A Book By ID - Planning
      • Retrieving A Book By ID - Implementation
      • Summary
    • Chapter 8: Adding Authentication to our API
      • Registering the User - Planning
      • Registering the User - Implementation
      • Logging the User In - Planning
      • Logging the User In - Implementation
      • Getting Authenticated User - Planning
      • Getting Authenticated User - Implementation
      • Summary
    • Chapter 9: Adding the Create, Update, and Delete Operations to our API
      • Creating A Book Listing - Planning
      • Creating A Book Listing - Implementation
      • Updating A Book Listing By ID - Planning
      • Updating A Book Listing By ID - Implementation
      • Deleting A Book Listing By ID - Planning
      • Deleting A Book Listing By ID - Implementation
      • Summary
    • Chapter 10: Testing our API
      • Testing the Request
      • Testing the Middleware
      • Testing the Validation
      • Testing the Domain
      • Testing the Event
      • Testing the Response
      • Testing the Controller
      • Integration Test
      • Summary
  • Conclusion
    • Final Words
  • Bonus!
    • Refactoring to HATEOAS
  • Appendix
    • Sources & References
Powered by GitBook
On this page
  • URI
  • Hostname
  • Query Parameter
  • Header
Edit on GitHub
  1. Part 2: The Theory
  2. Chapter 3: RESTful API Design Guidelines and "Best Practices"

Versioning Strategies

PreviousMetadata DesignNextSecurity Considerations

Last updated 3 years ago

Any RESTful API (internal or public-facing) that has been around the block for a long period of time will eventually experience some sort of version change. API versioning essentially boils down to supporting forwards and backwards compatibility as well as supporting multiple different API versions.

API versioning was never an issue for me since I had only worked for small to medium sized businesses in the beginning of my career. However, as I progressed further in my career and gained more experience working with older systems, the concept of versioning became more apparent. The concept of being able to label versions so that the client consuming your RESTful API can easily comprehend it is an important feature of your API.

In this section we will talk about the 4 main versioning strategies that can be applied when building your RESTful API. There is no real "correct" or "best" approach, but rather pros and cons to each of them.

URI

This is by far the most common and most popular method of versioning. Not only do the majority of developers already do this in their code bases, most of the large tech companies use this method as well. It is extremely easy for both developers developing the API and for clients consuming the API. It is a very visible, obvious, direct, and pragmatic.

However, the only problem with this approach is... well... it isn't considered RESTful (by the man himself).

Examples

https://api.website.com/v1/resources

https://www.website.com/api/v1/resources

Real World Examples

Hostname

The usage of hostnames as versioning is quite similar to using the URI. It's easy to understand from the client's perspective. There's quite a clear separation of different versions via the subdomains. The difficult part might be that one has to use DNS in order to split and manage versions over multiple servers, that could be both good and bad depending on the situation.

Examples

https://api-v1.website.com/resources

https://api-v2.website.com/resources

Real World Example

I've also seen a lot of the internal APIs built by companies that I worked at use this approach. Typically, different versions are used within the subdomains as well as a way to split up development, staging, and production environments.

Query Parameter

Using the optional query parameter is yet another popular method of versioning. It technically does follow REST since it is an optional parameter, which means it does not interfere with any concrete resources. However, I find that if not specified explicitly in the documentation, it's quite easy for developers to forget or to even know that there is a custom parameter required for a different version.

Examples

https://www.website.com/api/resources?version=1.0

https://www.website.com/api/resources?v=10-01-2049

Real World Example

Header

An API that expects a consumer to communicate its version preference through HTTP headers normally defines a custom HTTP header. If you take this approach, your custom header should be "x-SOMETHING". I actually quite like this method, but the only problem with it is that some developers (mainly junior ones) can get confused if they do not know about headers very well.

Example

Making a GET request with a custom x-version header.

GET /resources HTTP/1.1
Host: api.website.com
x-version: 1.0

Real World Example

Stripe:

PayPal:

Twitter:

League of legends:

Google:

Microsoft Azure:

https://stripe.com/docs/api/versioning
https://developer.paypal.com/docs/api/overview/#make-rest-api-calls
https://developer.twitter.com/en/docs/twitter-api/versioning
https://developer.riotgames.com/docs/lol
https://developers.google.com/gdata/docs/developers-guide?csw=1#updating-a-raw-http-client
https://docs.microsoft.com/en-us/rest/api/storageservices/Versioning-for-the-Azure-Storage-Services?redirectedfrom=MSDN#specifying-service-versions-in-requests
Roy Fielding's "official" comment on using the "v1" versioning approach.
https://developer.twitter.com/en/docs/twitter-api/versioning
https://developer.riotgames.com/docs/lol
https://developers.google.com/gdata/docs/developers-guide?csw=1#updating-a-raw-http-client
https://docs.microsoft.com/en-us/rest/api/storageservices/Versioning-for-the-Azure-Storage-Services?redirectedfrom=MSDN#specifying-service-versions-in-requests