Versioning REST API
Versioning REST API
http://www.example.com/api/1/products
One way to version a REST API is to include the version number in the URI
path.
xMatters uses this strategy, and so do DevOps teams at Facebook, Twitter,
Airbnb, and many more.
The internal version of the API uses the 1.2.3 format, so it looks as follows:
MAJOR.MINOR.PATCH
Major version: The version used in the URI and denotes breaking
changes to the API. Internally, a new major version implies creating a
new API and the version number is used to route to the correct host.
Minor and Patch versions: These are transparent to the client and
used internally for backward-compatible updates. They are usually
communicated in change logs to inform clients about a new
functionality or a bug fix.
This solution often uses URI routing to point to a specific version of the API.
Because cache keys (in this situation URIs) are changed by version, clients
can easily cache resources. When a new version of the REST API is
released, it is perceived as a new entry in the cache.
http://www.example.com/api/products?version=1
Another option for versioning a REST API is to include the version number
as a query parameter.
REST APIs can also be versioned by providing custom headers with the
version number included as an attribute.The main difference between this
approach and the two previous ones is that it doesn’t clutter the URI with
versioning information.
curl -H “Accept:
application/vnd.xm.device+json; version=1” http://www.example.com/api/
products
One of the drawbacks of this approach is that it is less accessible than URI-
versioned APIs: Requiring HTTP headers with media types makes it more
difficult to test and explore the API using a browser.
Summary
o A change in the format of the response data for one or more calls.
o Change in the response type.
o Remove any part of the API.
How to Version
The most commonly used approaches fall into three categories:
o URI Versioning
o Versioning using Custom Request Header
o Versioning using Accept Header
AD
URI Versioning
URI versioning is the most straightforward approach. It specified in the
URL as a query string. It violates the principle that a URI should refer to a
unique resource. You are also guaranteed to break client integration when
a version is updated. Twitter uses URI versioning.
Example
http://api.demo.com/v1
http://apiv1.demo.com
The version need not be numeric, nor specified using v[x] syntax.
Alternatives include the date, project name, season, or other identifiers
that are meaningful enough to change as the version change.
Versioning using Custom Request Header
A custom header allows us to preserve our URLs. It is a duplicate of the
content negotiation behavior implemented by the existing Accept header.
Version information is specified in the Request Header without the need
for any change in the URL. Microsoft uses the request header versioning.
The user cannot access request header versioning in the normal browser
(chrome). We are required a special plugin to access them on the browser.
Example
Accept-version: v1
Accept-version: v2
Example
Accept: application/vnd.demo.v1+json
Accept:application/vnd.demo+json;version=1.0
URI Versioning
Step 1: Create a class with the name PersonV1.java in the
package com.javatpoint.server.main.versioning. PersonV1 denotes
the first version of API. The initial version of API has a name variable.
PersonV1.java
1. package com.javatpoint.server.main.versioning;
2. public class PersonV1
3. {
4. private String name;
5. }
Step 2: Over a period, we recognize the need for having the first name
and last name separately. So we created a class with the
name Person2.java. It denotes the second version of API.
PersonV2.java
1. package com.javatpoint.server.main.versioning;
2. public class PersonV2
3. {
4. private Name name;
5. }
Step 3: Create a class with the name Name.java that has two
variables firstName and lastName separately.
AD
Name.java
1. package com.javatpoint.server.main.versioning;
2. public class Name
3. {
4. private String firstName;
5. private String lastName;
6. }
The old version is still returning the full name, and the second version is
returning firstName and lastName separately. Now we are required to
create two different versions of the same service.
Let's see how to create two different versions of the same service and
what are the different versions of the service are present.
Name.java
1. package com.javatpoint.server.main.versioning;
2. public class Name
3. {
4. private String firstName;
5. private String lastName;
6. //no argument constructor
7. public Name()
8. {
9.
10.}
11.public Name(String firstName, String lastName)
12.{
13.super();
14.this.firstName = firstName;
15.this.lastName = lastName;
16.}
17.public String getFirstName()
18.{
19.return firstName;
20.}
21.public void setFirstName(String firstName)
22.{
23.this.firstName = firstName;
24.}
25.public String getLastName()
26.{
27.return lastName;
28.}
29.public void setLastName(String lastName)
30.{
31.this.lastName = lastName;
32.}
33.}
PersonV1.java
1. package com.javatpoint.server.main.versioning;
2. public class PersonV1
3. {
4. private String name;
5. //no argument constructor
6. public PersonV1()
7. {
8. super();
9. }
10.public PersonV1(String name)
11.{
12.super();
13.this.name = name;
14.}
15.public String getName()
16.{
17.return name;
18.}
19.public void setName(String name)
20.{
21.this.name = name;
22.}
23.}
PersonV2.java
1. package com.javatpoint.server.main.versioning;
2. public class PersonV2
3. {
4. private Name name;
5. public PersonV2()
6. {
7. super();
8. }
9. public PersonV2(Name name)
10.{
11.super();
12.this.name = name;
13.}
14.public Name getName()
15.{
16.return name;
17.}
18.public void setName(Name name)
19.{
20.this.name = name;
21.}
22.}
PersonVersioningController.java
1. package com.javatpoint.server.main.versioning;
2. import org.springframework.web.bind.annotation.RestController;
3. import org.springframework.web.bind.annotation.GetMapping;
4. @RestController
5. public class PersonVersoningController
6. {
7. //this method is for the first version that returns the entire name
8. @GetMapping("v1/person")
9. public PersonV1 personv1()
10.{
11.return new PersonV1("Tom Cruise");
12.}
13.//this method is for the second version that returns firstName and lastName sepa
rately
14.@GetMapping("v2/person")
15.public PersonV2 personv2()
16.{
17.return new PersonV2(new Name("Tom", "Cruise"));
18.}
19.}
Step 8: Open the Postman and send a GET request with the URI
http://localhost:8080/v1/person. It returns the full name, as shown in the
following image.
o Change the URI for the first method from /v1/person to /person/param.
o Change the name of the method from personV1 to paramV1.
o Similarly, change the URI for the second method from /v2/person to
/person/param.
Both the methods have the same get mapping, so we will distinguish
them by using the value and params attribute. The value attribute
contains the URI, which we want to use, and the params attribute contains
the parameter which distinguishes between versions.
PersonVersoningController.java
1. package com.javatpoint.server.main.versioning;
2. import org.springframework.web.bind.annotation.GetMapping;
3. import org.springframework.web.bind.annotation.RestController;
4. @RestController
5. public class PersonVersoningController
6. {
7. //this method is for first version that returns the entire name
8. @GetMapping(value="/person/param", params="version=1")
9. public PersonV1 personV1()
10.{
11.return new PersonV1("Tom Cruise");
12.}
13.//this method is for second version that returns firstName and lastName separate
ly
14.@GetMapping(value="/person/param", params="version=2")
15.public PersonV2 personV2()
16.{
17.return new PersonV2(new Name("Tom", "Cruise"));
18.}
19.}
Now, move to Postman and send a GET request with the URI
http://localhost:8080/person/param?version=1. It returns the full name, as
shown in the following image.
o Select the Headers tab and set key: X-API-VERSION and Value: 1.
o Type the URI http://localhost:8080/person/header and send a GET request.
AD
o Select the Headers tab and set key: Accept and Value:
application/vnd.company.app-v1+json.
o Uncheck the X-API-VERSION key.
o Type the URI http://localhost:8080/person/produces and send a GET
request.