Our service has shipped our api with a public version we'll support for at least 18 months. We're now starting on some new features which will be in v2.
I'm reading up on it but haven't found the answer yet.
When designing a new API Version for a public webservice
Our V2 entities have at least all of the same entities as V1 items. However they often add some new properties for V2 items. With this in mind...
When a customer does a v1 API Version Get, should we show v2 items at all?
How about when they do a V2 get?
V2 adds some properties that v1 doesn't have. With a V2 get, should we return V1 items as well? In that case, should we just leave those properties empty?
What's the 'Right way' to do this?
There are always edge cases in specific API implementations, but if we're talking about REST over HTTP, then every API version where said entity exists should be available forward and backward.
First, let's consider a resource. Let's say you have /order/123
. Remember that REST is Representational State Transfer. The API version should not be thought of as a version in binary code nor an API as a method that is invoked. HTTP is the API and GET
is the method (think http.get(request)
). That being said, the API version indicates how you want the entity to be represented. An API version is better thought of as a form of media type negotiation.
If I'm a customer or a client integrating with the Orders API, I'm not thinking specifically about API versions. I just know I have order 123
. This order exists regardless of the API version. Client code only cares about an API version in the context of "I know/expect an order to look like...". This means that all orders should be available in all versions. This behavior likely requires that you need some special handling or data transfer objects (DTOs) to make things work as expected over the wire. This could be hiding/removing new members or filling in missing members, if possible. This can lead to a lot of extra work, which is why it's important to have a sound versioning policy such as N-2
.
You've elected to version by query string so that puts you in a pretty good position. Making the query parameter required in all versions is an excellent policy because the client should always have to explicitly ask for what they want. We all know what happens when the server assumes. Versioning by URL segment, despite its popularity, is the worst way to version. It violates the Uniform Interface REST constraint. A resource is identified by its URL path - the whole path. A human being sees 123
as the identifier, but to HTTP it's order/123
. v1/order/123
and v2/order/123
are not different orders (as the URL implies), rather they are different representations. The query string never identifies a resource so that is a reasonable, if not pragmatic approach, to versioning as opposed to true media type negotiation.