7

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 ?

3
  • seems like accept-params in the Accept header is not being used by spring. Commented Apr 24, 2017 at 17:42
  • Possible duplicate of stackoverflow.com/questions/34425316/… Commented May 3, 2017 at 19:59
  • off topic dont use system.out use logger whenever possible Commented May 10, 2017 at 8:24

2 Answers 2

4

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:

Sign up to request clarification or add additional context in comments.

Comments

2
+50

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

2 Comments

Thanks @rhinds for the response
It would have been better to include some code examples

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.