Search code examples
javaapirestful-architectureapi-versioning

How to solve obstacles related to API version


I am having a restfull service and there are more than 20 clients thats is using this service.

@Path("/provider")
public class Provider{

@Path("/simpleprovider")
@GET
public String getProvider(){
return "Simple Provider";
}
}

Now i have decided to introduce version in service, i have google alot, read my articles but i am totally confused how should i do? suppose i change URI for new service like @Path("/provider/v1") than how should i provide support for existing clients ? by considering this thing should i have to provide change on every client whenever api new version comes in action ?

After Googling i found that there are 3 ways to provide versioning

  1. URL versioning

  2. custom request header

  3. content type

but could not find any practical example please help me in this regard

http://stackoverflow.com/questions/389169/best-practices-for-api-versioning http://www.narwhl.com/2015/03/the-ultimate-solution-to-versioning-rest-apis-content-negotiation/ http://restcookbook.com/Basics/versioning/

http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html

http://www.lexicalscope.com/blog/2012/03/12/how-are-rest-apis-versioned/

Any help will be greatly appreciated


Solution

  • Versioning a service can be very tricky and is always a big decision when determining the versioning strategy. Especially if you have people using the service. From my experience here are some things to consider:

    1. Understand and communicate when and if you plan on sun setting versions of your API. The last thing you want to have is a problem where you are having to upkeep 10 different versions of an API.

    2. Understand if a version change is absolutely necessary. A good rule of thumb is if core functionality is changing or if the contract can potentially break someones software that is integrating with your API. Here are some things to consider when determining if you really need to version:

      • If you are removing fields from a resource.
      • If you are removing (or updating) a URL (or method).
      • If an existing endpoint (or method) logic is going to change such that it would require a consumer to re-implement.
      • Overall, if a change that you make would break someone integrating with your API.
    3. Are you going to require database changes that would not be backwards compatible with your previous version(s)? This is when versioning can get really fun (sarcastically) because now you might have to make your database backwards compatible which, in my experience, can be difficult problem to deal with moving forward.

    To answer your question, though, I have found the best way to version to be in the URL. Be very simple and deliberate with your versioning so that it is crystal clear for your integrator. For example:

    • GET /v1/products/{id} // Version 1
    • GET /v2/products/{id} // Version 2

    ** If you decide on URL versioning then my advice is to put do "v" for version and a SINGLE number like 1 or 2. Don't get into versions, sub versions, etc... This will make your API seem like it revs a lot which can cause concern for consumers. Also, keep the version as FAR left of the URL as possible. The idea is that everything to the right of the version is the new versioned resource. I would AVOID using headers to version your service. You don't want to hide versions from your consumer. Be as transparent and explicit about versioning as you possibly can.

    Versioning in the URL allows you to also do some useful routing and things on your web server and proxies as well. You can either version like this in your actual code, for example:

    [HttpGet("v1/products")]
    public Product GetProduct(string id)
    {
        return _repository.GetProduct(id);
    }
    

    or you can version using your web server by setting up virtual directories (or whatever). Then your code might look something like this instead:

    [HttpGet("products")]
    public Product GetProduct(string id)
    {
        return _repository.GetProduct(id);
    }
    

    However you decide to version it is very important to think about the pro's and con's of each decision and weigh them because if you are running an API that people are using the bad decisions will catch up to you in a hurry.