I am trying to use content negotiation to implement API versioning since putting a version in the URI is not RESTful. It doesn't seem possible with Spring MVC since the consumes/produces attributes of the @RequestMapping are not taken into account when resolving controller methods, just the path. For the sake of discussion let's say I have this controller
@RestController
@RequestMapping(path = "/foo")
public class FooController {
@RequestMapping(path = "{id}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
public Foo getFoo(@PathVariable Long id) {
return repository.findOne(id);
}
@RequestMapping(path = "{id}", method = RequestMethod.GET, produces = { "application/vnd.com.me.model.v1+json" })
@ResponseBody
public FooV1 getFooV1(@PathVariable Long id) {
return repositoryV1.findOne(id);
}
...
}
The REST API is "GET /foo/1" or "GET /foo/2" etc but I want to be able to send either
Accept: application/json
or
Accept: application/vnd.com.me.model.v1+json
and have it go to the correct controller method. Ignore the issue of how best to represent the model. This is just about getting Spring MVC to let me have a single REST URI handle different content types. This obviously applies to the other HTTP methods, PUT, POST, etc. as well. Given the above controller definition you get an error as Spring tries to resolve the mappings, some variation of "sorry there's already a mapping for '/foo/{id}'."
Have I missed something that will allow me to achieve this?