Is there a standard or convention on whether location retuned by a REST server should also include the version information? Per REST, the URI is to a resource so by that definition, the URI returned in the Location header should not have a version.
But a GET on the location returned by the server is supposed to work, but it fails if version information is not added to the URI. Is the client supposed to know the preferred version of the server, especially when there may be API gateways that aggregate multiple backend microservices that are on different API versions?
Is there a standard on this, should or shouldn't the server return the API version in the response?
CodePudding user response:
There is no standard when it comes to versioning and REST. REST is a system of constraints. There are, however, methods of versioning that adhere to the constraints and those that do not (such as in the URL path).
An API version should not be thought of in the same way as a version for binaries. While "API version" is a widely accepted term, it's a bit of a misnomer. An API version doesn't indicate which method to call for an API, it indicates the format. Remember that HTTP is the API. HTTP does not have method overloads or versions. What's behind that is an implementation detail.
This means that a media type best describes and serves the purpose of an API version, even if there are other ways to convey it. The server's job is to tell you where a resource is located via Location when you create a resource with a server-generated identifier. It is not obligated to tell you what format you (the client) want it in. Since you just created a resource specifying a specific API version (or format), you should know how to send a GET to retrieve that resource.
The same rules and logic apply for HATEOAS. If the server provides the location of related resources, it cannot know what API version (or format) of those resources that you - the client - want. The independent evolution of services often results in heterogenous versions across APIs.
Exactly how these concepts can be applied to microservices is a bit off-topic, but it is entirely possible that one service writes a resource in a v1 format, while another service reads the resource in a v2 or v3 format. Regardless, the Location of the resource should be the same and is shareable across service boundaries.
CodePudding user response:
Per REST, the URI is to a resource so by that definition, the URI returned in the Location header should not have a version.
That doesn't quite follow.
a URI is a resource identifier; it identifies a resource, where "any information that can be named can be a resource (Fielding, 2000).
In general, the representation of a resource is a function of time; and a response to a GET request is expected to return the latest version of that resource.
But, if that's not suitable, then it is fine to instead model a different resource that has a representation which is not a function of time.
/705604c9-2e1f-43c8-953e-7659f44f5b32 <-- "version 0"
/bbd02ea3-96d8-41dd-ac70-4748bd3e93ac <-- "version 1"
/86d09182-5002-4568-8a4a-352a75daa40c <-- "version 2"
/32a856ef-4894-49f4-8e27-ab3ab41de71f <-- "latest"
Of course, these identifiers are not particularly helpful to a human trying to recognize them, so you'd probably want to use a friendlier spelling convention
/foo/history/0
/foo/history/1
/foo/history/2
/foo
For API versions, your humans will probably be happier with different prioritization of the path segments
/api/v0/foo
/api/v1/foo
/api/v2/foo
/api/foo
In contexts where backwards compatibility is important, you want to be really careful about changing the meaning of a resource.
In cases where the meanings are constant, but the representations are changing over time, then you might use content negotiation (either pro-active or reactive) to help clients to retrieve a representation with the right schema. So if someone tries to GET the resource, but doesn't describe one of your supported schema in the Content-Type header, then maybe you send them an 300 Multiple Choices response, and go from there.
(At this point, we're starting to enter the realm of bespoke clients, which is a bit outside the scope of REST, which itself focuses on general purpose components.)
