Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring MVC controller versioning

I have a spring boot application , which have a spring MVC controller. I am trying to version my rest api using Accept header.

The following is how my Controller looks like

RestController
@RequestMapping(value = "/private/")
public class AppleController {

  private final AppleService appleService;

  public AppleController(AppleService appleService) {
    this.appleService = appleService;
  }

  @GetMapping(value = "apples/{id}", produces = "application/json; v=1.0",
      headers = "Accept=application/json; v=1.0")
  public ResponseEntity getByappleId(@PathVariable("id") Long appleId) {
    System.out.println("version1");

    GetByappleIdResponse response = appleService.findByappleId(appleId);

    return new ResponseEntity<>(response, HttpStatus.OK);
  }



  @GetMapping(value = "apples/{id}", produces = "application/json; v=2.0",
      headers = "Accept=application/json; v=2.0")
  public ResponseEntity getByappleId2(@PathVariable("id") Long appleId) {
    System.out.println("version2");
    GetByappleIdResponse response = appleService.findByappleId2(appleId);
    return new ResponseEntity<>(response, HttpStatus.OK);
  }

Irrespective of the version that I am passing in the Accept header when calling the API always "getByappleId" method is called, hence only version 1 response is returned.

Is there anything wrong in my controller ?

like image 236
Prabhakar D Avatar asked Apr 24 '17 17:04

Prabhakar D


2 Answers

There are many options to implement versioning of REST API:

  • suggested in the comments approach for manually routing your request;
  • making version as a part of your Accept header value, f.e.:

    (headers = "Accept=application/vnd.name.v1+json")

    (headers = "Accept=application/vnd.name.v2+json")

  • making version as a part of your mapping:

    @GetMapping("apples/v1/{id})"

    @GetMapping("apples/v2/{id})

So you need to decide which way to go. Some useful links:

  • Versioning a REST API
  • Best practices for API versioning?
like image 60
dmytro Avatar answered Nov 03 '22 00:11

dmytro


As described in this answer: https://stackoverflow.com/a/34427044/258813 (and mentioned in the comments) Spring does not support routing using the headers like that.

If you want to support routing via a version header, I would recommend a custom routing condition and annotation - certainly if you are building a large API, it will result in less code and a more elegant solution.

You would define some annotation like @ApiVersion(1) that you can add to any method that is also a request mapping and then add the custom routing condition and it will behave correctly.

I have described using custom routing conditions and annotations (based on subdomains - but that could easily be switched to check headers instead) here: http://automateddeveloper.blogspot.co.uk/2014/12/spring-mvc-custom-routing-conditions.html

like image 20
rhinds Avatar answered Nov 03 '22 00:11

rhinds