简体   繁体   中英

Versioning of coupled RESTful APIs with HATEOAS

We have a ProductsAPI to browse products available at our site which is consumed by our mobile Apps (Android & iOS). Following is the basic design:

URL: /api/products/
Response:
[
    {
        "id" : 123,
        "name" : "abc",
        "detailsUrl" : "/api/products/123"
    },
    {
        "id" : 124,
        "name" : "xyz",
        "detailsUrl" : "/api/products/124"
    }
]

Here, detailsUrl contains the API URL for ProductDetails page.

Now, we have a requirement to make some changes in the response of ProductDetails API in new versions of apps and need to version it. The URL will be changed to - /api/v2/products/{id} (we use API versioning through URL).

Since we do not want the new response in previous version of Apps, we need to create a new version of ProductsAPI also which will send new ProductDetailsAPI url in response.

The APIs are coupled this way. If we change version of any child API, parent API version also need to be changed. What is the recommended way to handle this issue? Should we change way of versioning our APIs (use headers or something)?

This is one of the consequences of versioning in the URL segment. I would recommend not doing that. For HATEOAS, the hypermedia should only report the identity of the related resources. It's up to the client to decide which API version they want to use.

In large APIs, it's common for services to have incongruent versions. This causes a number of issues with any approach that includes an API version in the provided link.

  1. The service advertising the link now either makes an assumption the related resource has the same resource version or has unwanted coupling to generate the correct link
  2. The service doesn't know what API version client wants or is aligned to. A client might be using api/orders 1.0 and api/salespeople 2.0. A service cannot know this and it's the responsibility of the client. If the service bakes the version in the link, it may not be what the client wants making it nearly worthless in the context of HATEOAS

In my opinion, there is no logical difference between api/products/123 and api/v2/products/123 . At the end of the day both URLs refer to a product with the identifier 123. The API version is indicating a different representation of that product, but not a different product. To that end, a HATEOAS implementation should return the links in the form of api/products/123 and let the client decide the representation by API version using a query string, header, media type, etc. The URL segment method is the only one that cannot work this way.

I'd recommend either a whole new version, so parent and child both add a /v2 into their URLs, or the use of media types. The idea of Media Types is that the clients send Content-Type headers to specify what version of the response should be returned for each resources. Using this approach avoids having to re-version a whole API, but does mean version checking for every endpoint.

A good example of media types in use is the GitHub API, you might find it useful to read the docs here: https://developer.github.com/v3/media/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM