API versioning through a custom header

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

API versioning through a custom header

Raúl Guerrero Deschamps
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

Gili
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

williamrbowen
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.

On Wed, Apr 6, 2016 at 9:06 AM, Gili T. <[hidden email]> wrote:
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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

Mark Thornton
In reply to this post by Gili
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

On 6 April 2016 at 14:06, Gili T. <[hidden email]> wrote:
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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

Gili
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

On 6 April 2016 at 14:06, Gili T. <[hidden email]> wrote:
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


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

Raúl Guerrero Deschamps
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?




2016-04-06 8:27 GMT-05:00 cowwoc <[hidden email]>:
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

On 6 April 2016 at 14:06, Gili T. <[hidden email]> wrote:
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



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

DiFrango, Ronald (CONT)
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


From: Raúl Guerrero Deschamps <[hidden email]>
Reply-To: "[hidden email]" <[hidden email]>
Date: Thursday, April 14, 2016 at 10:32 PM
To: "[hidden email]" <[hidden email]>
Subject: [Jersey] Re: API versioning through a custom header

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?




2016-04-06 8:27 GMT-05:00 cowwoc <[hidden email]>:
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

On 6 April 2016 at 14:06, Gili T. <[hidden email]> wrote:
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





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.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: API versioning through a custom header

Gili
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?




2016-04-06 8:27 GMT-05:00 cowwoc <[hidden email]>:
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

On 6 April 2016 at 14:06, Gili T. <[hidden email]> wrote:
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




Loading...