|
|
Hi all,
After researching API versioning with Jersey a bit, the only way I see this happening is through modifying the Accept header and use a special MIME type, and then if the MIME type ends with +xml or +json it's smart enough to understand what serializer to use.
Now, what if, because of client restrictions, I can't handle custom MIME types and such, and instead I'd like to use another recommended versioning pattern which would be adding a header to the HTTP request called version, and place the version number there.
That way I could do something like
@GET("/myObj") @Consumes(MediaType.APPLICATION_JSON) @Header("version", "1.0") public JsonResponse myV1method() {}
@GET("myObj") @Consumes(MediaType.APPLICATION_JSON)
@Header("version", "2.0")
public JsonResponse myV2method() {}
Currently, how could I choose which jersey annotated java method to use depending on what the version header value is?
Thanks,
Raul
|
|
I'm also interested in this. Last I heard it wasn't possible because @Path chooses a class or method without first examining the headers. I believe this is a very important use-case.
Gili On Wed, Apr 6, 2016, 03:34 Raúl Guerrero Deschamps < [hidden email]> wrote: Hi all,
After researching API versioning with Jersey a bit, the only way I see this happening is through modifying the Accept header and use a special MIME type, and then if the MIME type ends with +xml or +json it's smart enough to understand what serializer to use.
Now, what if, because of client restrictions, I can't handle custom MIME types and such, and instead I'd like to use another recommended versioning pattern which would be adding a header to the HTTP request called version, and place the version number there.
That way I could do something like
@GET("/myObj") @Consumes(MediaType.APPLICATION_JSON) @Header("version", "1.0") public JsonResponse myV1method() {}
@GET("myObj") @Consumes(MediaType.APPLICATION_JSON)
@Header("version", "2.0")
public JsonResponse myV2method() {}
Currently, how could I choose which jersey annotated java method to use depending on what the version header value is?
Thanks,
Raul
|
|
Two quick thoughts on this -
1) Wouldn't a @PreMatching request filter be able to match before the @Path chooses a method?
2) In the past we solved this by fronting the Jersey services with a load balancer that would look at the version header and route the request to an appropriate cluster depending on major version. Downside is we had to run multiple servers supporting multiple versions concurrently, but the upside was that they were sandboxed and didn't have conflicts with methods or JAR dependencies, etc.
Of course, not everyone has control over their environment to take such an approach.
|
|
You could use a filter to modify the request before matching takes place. I don't know exactly what changes are possible, but it seems likely that a filter could change the media type based on some other header (such as x-version).
Mark
|
|
Based on memory, this does not help.
When I tried implementing this, I used a content-type of
"vnd.mycompany.sometype+json; version=1" and @Path happily ignored
this and chose a class/method without looking at @Consumes at all.
Gili
On 2016-04-06 9:25 AM, Mark Thornton wrote:
You could use a filter to modify the request before
matching takes place. I don't know exactly what changes are
possible, but it seems likely that a filter could change the
media type based on some other header (such as x-version).
Mark
|
|
Cowwoc,
For the MIME type versioning, you're using it incorrectly, for adding the version in the MIME type, you have to define something like "vnd.mycompany.sometype.v1+json" and not the ; version=1 thing you mention
Jersey, guys, what's your take on using something like @Header("version", "1.0") and such like I mentioned? or should we standardise it even more and use @Version("1.0") and Jersey will handle the header "version: ${version}" by itself?
Any thoughts?
|
|
Rahul,
We found the same thing that you did, namely we had to use a custom MIME type and we wrote a customer Media Type filter that converted from some thing like application/json;v=3 to the custom one so that the Jersey routing worked correctly.
Thanks,
Ron
Cowwoc,
For the MIME type versioning, you're using it incorrectly, for adding the version in the MIME type, you have to define something like "vnd.mycompany.sometype.v1+json" and not the ; version=1 thing you mention
Jersey, guys, what's your take on using something like @Header("version", "1.0") and such like I mentioned? or should we standardise it even more and use @Version("1.0") and Jersey will handle the header "version: ${version}" by itself?
Any thoughts?
The information contained in this e-mail is confidential and/or proprietary to Capital One and/or its affiliates and may only be used solely in performance of work or services for Capital One. The information transmitted herewith is intended only for use by the individual or entity to which it is addressed. If the reader of this message is not the intended recipient, you are hereby notified that any review, retransmission, dissemination, distribution, copying or other use of, or taking of any action in reliance upon this information is strictly prohibited. If you have received this communication in error, please contact the sender and delete the material from your computer.
|
|
In reply to this post by Raúl Guerrero Deschamps
Say we have:
Accept: x-mycompany.sometype; version=1
While you are right that the version is not strictly part of the
content-type, it considered a parameter of the Accept header and
as such servers are *required* to take it into consideration. See
"accept-ext" at https://tools.ietf.org/html/rfc7231#section-5.3.2
I believe it is a bug for @Consumes to match exclusively based on
the content-type, ignoring Accept parameters because doing so
violates the HTTP specification.
Gili
On 2016-04-14 10:32 PM, Raúl Guerrero Deschamps wrote:
Cowwoc,
For the MIME type versioning, you're using it incorrectly,
for adding the version in the MIME type, you have to define
something like "vnd.mycompany.sometype.v1+json" and not the ;
version=1 thing you mention
Jersey, guys, what's your take on using something like
@Header("version", "1.0") and such like I mentioned? or should
we standardise it even more and use @Version("1.0") and Jersey
will handle the header "version: ${version}" by itself?
Any thoughts?
|
|