Java – simple rest resource versioning in jax-rs based implementations?
The best practice of rest resource version control is to put the version information into the accept / content type header of HTTP request to keep the URI intact
The following is a sample request / response of the rest API used to retrieve system information:
==> GET /api/system-info HTTP/1.1 Accept: application/vnd.COMPANY.systeminfo-v1+json <== HTTP/1.1 200 OK Content-Type: application/vnd.COMPANY.systeminfo-v1+json { “session-count”: 19 }
Note the version specified in the MIME type
This is another request / response for version 2:
==> GET /api/system-info HTTP/1.1 Accept: application/vnd.COMPANY.systeminfo-v2+json <== HTTP/1.1 200 OK Content-Type: application/vnd.COMPANY.systeminfo-v2+json { “uptime”: 234564300,“session-count”: 19 }
For more instructions and examples, see http://barelyenough.org/blog/tag/rest-versioning/.
Can this approach be easily implemented in Java based jax-rs implementations such as Jersey or Apache CXF?
The goal is to make several @ resource classes have the same @ path value, but provide the request according to the actual version specified in the MIME type?
I have been studying Jax - RS, especially Jersey, and have found no support Jersey does not have the opportunity to register two resources with the same path The replacement of webapplicationimpl class needs to be supported by the implementation
Can you suggest something?
Note: multiple versions of the same resource need to be available at the same time The new version may introduce incompatible changes
Solution
Jax - RS is sent to the method annotated with @ produces through the accept header So if you want Jax - rs to do your scheduling, you need to use this mechanism Without any extra work, you will have to create a method (and provider) for each media type you want to support
Nothing can prevent you from using several methods based on media types. All these methods are called normal methods to do this, but each time you add a new media type, you must update the method and add code
One idea is to add a filter to "filter" your accept header for sending That is, you can:
Accept: application/vnd.COMPANY.systeminfo-v1+json
And convert it to, simply:
Accept: application/vnd.COMPANY.systeminfo+json
At the same time, you extract version information for later use (perhaps in requests or other ad hoc mechanisms)
Jax - RS then schedules to a single method that handles "application / vnd. Company. Systeminfo JSON"
Then, the method uses "out of band" version information to handle the details in processing (for example, select the appropriate class load through OSGi)
Next, create a provider using the appropriate messagebodywriter Jax-rs will be the application / vnd COMPANY. Systeminfo JSON media type selection provider Your MBW will determine the actual media type (again based on the version information) and create the correct output format (again, perhaps assigned to the correct OSGi load class)
I don't know if MBW can override the content type header If not, you can delegate an earlier filter to override the part for you on the way out
This is a bit complicated, but if you want to use jax-rs scheduling instead of creating methods for each version of media type, this is a feasible way
Edit response comments:
Yes, in essence, you want Jax - rs to send to the correct class based on path and accept types Jax - RS is unlikely to be out of the box because it is a good example I haven't seen any Jax - RS implementations, but you can adjust one of the infrastructure levels to accomplish the required tasks
Perhaps another less intrusive option is to use an old trick in the Apache world, just create a filter based on the rewrite path of the accept header
So when the system gets:
GET /resource Accept: application/vnd.COMPANY.systeminfo-v1+json
You can rewrite it as:
GET /resource-v1 Accept: application/vnd.COMPANY.systeminfo-v1+json
Then, in your jax-rs class:
@Path("resource-v1") @Produces("application/vnd.COMPANY.systeminfo-v1+json") public class ResourceV1 { ... }
So, your client gets the right view, but your classes are properly scheduled by Jax - rs The only other problem is that if your class looks, your class will see the modified path instead of the original path (but if you like, your filter can be filled in as a reference in the request)
This is not ideal, but it is (mainly) free
This is an existing filter that can do what you want to do. If not, it may be used as an inspiration for you to do it yourself