You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Francesco Chicchiriccò <il...@apache.org> on 2015/06/08 08:05:12 UTC

[JAX-RS] Best practice for update methods

Hi,
we have several "update" methods in our JAX-RS services, with similar 
signature:

     @PUT
     @Path("{key}")
     @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
     void update(@NotNull @PathParam("key") String key, @NotNull 
ResourceTO resourceTO);

For various reasons, the key value is already contained in the 
ResourceTO bean; this leads to kind of redundant invocations like as

resourceService.update(resourceTO.getKey(), resourceTO);

I was wondering whether this situation can be improved by using @BeanParam:

     void update(@BeanParam ResourceTO resourceTO);

by annotating ResourceTO#setKey() with @Path("{key}").

It seems that with such setup only "key" is evaluated, e.g. the rest of 
ResourceTO instance is left empty.

Am I missing something? Any suggestion to fix the original problem?

Thanks for your support.
Regards.



Re: [JAX-RS] Best practice for update methods

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Francesco, thanks for the confirmation,

@BeanParam refers to a bean which captures parameters like query, path, 
header, matrix or any of JAX-RS contexts, but not the actual body.
Cheers, Sergey
On 10/06/15 14:57, Francesco Chicchiriccò wrote:
> On 09/06/2015 15:34, Francesco Chicchiriccò wrote:
>> On 09/06/2015 15:17, Sergey Beryozkin wrote:
>>> Hi Francesco
>>> See https://issues.apache.org/jira/browse/CXF-6447,
>>>
>>> So you'd be able to optimize the signature if still preferred, the
>>> server code would stay completely portable, though only CXF proxies
>>> would likely to work with such signatures in the short term at least
>>
>> Wow, cool stuff :-)
>>
>> I'll check with CXF 3.1.2-SNAPSHOT and let you know how it goes.
>
> I confirm it works like a charm; at first I had troubles because I was
> using
>
> @PUT
> @Path("{key}")
> void update(@BeanParam ResourceTO bean);
>
> but then I checked again and changed to
>
> @PUT
> @Path("{key}")
> void update(ResourceTO bean);
>
> Thanks again.
> Regards.
>
>>> On 08/06/15 10:43, Sergey Beryozkin wrote:
>>>> Sorry, that will not work with the proxies as they won't be able to
>>>> resolve the {key} :-), with webclients only...
>>>>
>>>> I wonder if we can explore your idea on the client side and try to
>>>> resolve a variable if the body bean is available...I'll try to
>>>> experiment a bit later on
>>>>
>>>> Thanks, Sergey
>>>>
>>>>
>>>> On 08/06/15 10:40, Sergey Beryozkin wrote:
>>>>> Hi Francesco,
>>>>>
>>>>> By the way, it is fine to have something like this:
>>>>>
>>>>> @PUT
>>>>> @Path("{key}")
>>>>> public void update(ResourceTo bean) {}
>>>>>
>>>>> That can actually be the optimal signature, if the bean contains
>>>>> the key
>>>>> then it can be taken from the bean and if not - then from UriInfo by
>>>>> analyzing the path value. Often a Path variable is also represented
>>>>> with PathParam but it is not a requirement
>>>>>
>>>>> Cheers, Sergey
>>>>>
>>>>> On 08/06/15 10:32, Francesco Chicchiriccò wrote:
>>>>>> Hi Sergey,
>>>>>> thanks for your response.
>>>>>>
>>>>>> On 08/06/2015 11:16, Sergey Beryozkin wrote:
>>>>>>> Hi Francesco
>>>>>>>
>>>>>>> Sure, you can try:
>>>>>>>
>>>>>>> @PUT
>>>>>>> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>>>>>>> void update(@NotNull ResourceTO resourceTO);
>>>>>>>
>>>>>>> Omitting the extra @Path completely and getting the key out of
>>>>>>> ResourceTo bean:
>>>>>>>
>>>>>>> PUT /resources
>>>>>>>
>>>>>>> <Resource>
>>>>>>>   <key>1</key>
>>>>>>>   <!- the rest of the representation -->
>>>>>>> </Resource>
>>>>>>>
>>>>>>> given that the key is available there.
>>>>>>>
>>>>>>>
>>>>>>> That said, if we were to abstract away from the the redundant proxy
>>>>>>> code where the key is specified twice during the invocation, one can
>>>>>>> say PUT targets an individual resource representation which is
>>>>>>> indeed
>>>>>>> identified as /resources/{key}. Optimizing the {key} away would lead
>>>>>>> to a slightly unbalanced space:
>>>>>>>
>>>>>>> // GET the 1st resource
>>>>>>> GET /resources/1
>>>>>>> // Update the 1st resource
>>>>>>> PUT /resources
>>>>>>>  (the representation with the key)
>>>>>>>
>>>>>>> My opinion has always been that ultimately the more practical it is
>>>>>>> the better as opposed to the purer the better. It might be
>>>>>>> reasonable
>>>>>>> to support both styles:
>>>>>>>
>>>>>>> PUT /resources/1
>>>>>>>
>>>>>>> POST /resources
>>>>>>>
>>>>>>> as POST is usually deals with the collection of resources and I
>>>>>>> guess
>>>>>>> it may be reasonable to suggest that POSTing to a collection which
>>>>>>> already contains an element with the same key means the actual
>>>>>>> update.
>>>>>>
>>>>>> I'd agree to keep
>>>>>>
>>>>>> PUT /resources/1
>>>>>>
>>>>>> which definitely makes sense; I thought there was some "magic" JAX-RS
>>>>>> annotation to identify an argument as request body so that I could
>>>>>> write
>>>>>>
>>>>>>       @PUT
>>>>>>       @Path("{key}")
>>>>>>       @Consumes({ MediaType.APPLICATION_XML,
>>>>>> MediaType.APPLICATION_JSON })
>>>>>>       void update(@BeanParam @RequestBody ResourceTO resourceTO);
>>>>>>
>>>>>> Given the considerations above, I'd say we'll probably leave things
>>>>>> unchanged.
>>>>>>
>>>>>> Regards.
>>>>>>
>>>>>>> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>>>>>>>> Hi,
>>>>>>>> we have several "update" methods in our JAX-RS services, with
>>>>>>>> similar
>>>>>>>> signature:
>>>>>>>>
>>>>>>>>      @PUT
>>>>>>>>      @Path("{key}")
>>>>>>>>      @Consumes({ MediaType.APPLICATION_XML,
>>>>>>>> MediaType.APPLICATION_JSON })
>>>>>>>>      void update(@NotNull @PathParam("key") String key, @NotNull
>>>>>>>> ResourceTO resourceTO);
>>>>>>>>
>>>>>>>> For various reasons, the key value is already contained in the
>>>>>>>> ResourceTO bean; this leads to kind of redundant invocations
>>>>>>>> like as
>>>>>>>>
>>>>>>>> resourceService.update(resourceTO.getKey(), resourceTO);
>>>>>>>>
>>>>>>>> I was wondering whether this situation can be improved by using
>>>>>>>> @BeanParam:
>>>>>>>>
>>>>>>>>      void update(@BeanParam ResourceTO resourceTO);
>>>>>>>>
>>>>>>>> by annotating ResourceTO#setKey() with @Path("{key}").
>>>>>>>>
>>>>>>>> It seems that with such setup only "key" is evaluated, e.g. the
>>>>>>>> rest of
>>>>>>>> ResourceTO instance is left empty.
>>>>>>>>
>>>>>>>> Am I missing something? Any suggestion to fix the original problem?
>>>>>>>>
>>>>>>>> Thanks for your support.
>>>>>>>> Regards.
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: [JAX-RS] Best practice for update methods

Posted by Francesco Chicchiriccò <il...@apache.org>.
On 09/06/2015 15:34, Francesco Chicchiriccò wrote:
> On 09/06/2015 15:17, Sergey Beryozkin wrote:
>> Hi Francesco
>> See https://issues.apache.org/jira/browse/CXF-6447,
>>
>> So you'd be able to optimize the signature if still preferred, the 
>> server code would stay completely portable, though only CXF proxies 
>> would likely to work with such signatures in the short term at least
>
> Wow, cool stuff :-)
>
> I'll check with CXF 3.1.2-SNAPSHOT and let you know how it goes.

I confirm it works like a charm; at first I had troubles because I was using

@PUT
@Path("{key}")
void update(@BeanParam ResourceTO bean);

but then I checked again and changed to

@PUT
@Path("{key}")
void update(ResourceTO bean);

Thanks again.
Regards.

>> On 08/06/15 10:43, Sergey Beryozkin wrote:
>>> Sorry, that will not work with the proxies as they won't be able to
>>> resolve the {key} :-), with webclients only...
>>>
>>> I wonder if we can explore your idea on the client side and try to
>>> resolve a variable if the body bean is available...I'll try to
>>> experiment a bit later on
>>>
>>> Thanks, Sergey
>>>
>>>
>>> On 08/06/15 10:40, Sergey Beryozkin wrote:
>>>> Hi Francesco,
>>>>
>>>> By the way, it is fine to have something like this:
>>>>
>>>> @PUT
>>>> @Path("{key}")
>>>> public void update(ResourceTo bean) {}
>>>>
>>>> That can actually be the optimal signature, if the bean contains 
>>>> the key
>>>> then it can be taken from the bean and if not - then from UriInfo by
>>>> analyzing the path value. Often a Path variable is also represented
>>>> with PathParam but it is not a requirement
>>>>
>>>> Cheers, Sergey
>>>>
>>>> On 08/06/15 10:32, Francesco Chicchiriccò wrote:
>>>>> Hi Sergey,
>>>>> thanks for your response.
>>>>>
>>>>> On 08/06/2015 11:16, Sergey Beryozkin wrote:
>>>>>> Hi Francesco
>>>>>>
>>>>>> Sure, you can try:
>>>>>>
>>>>>> @PUT
>>>>>> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>>>>>> void update(@NotNull ResourceTO resourceTO);
>>>>>>
>>>>>> Omitting the extra @Path completely and getting the key out of
>>>>>> ResourceTo bean:
>>>>>>
>>>>>> PUT /resources
>>>>>>
>>>>>> <Resource>
>>>>>>   <key>1</key>
>>>>>>   <!- the rest of the representation -->
>>>>>> </Resource>
>>>>>>
>>>>>> given that the key is available there.
>>>>>>
>>>>>>
>>>>>> That said, if we were to abstract away from the the redundant proxy
>>>>>> code where the key is specified twice during the invocation, one can
>>>>>> say PUT targets an individual resource representation which is 
>>>>>> indeed
>>>>>> identified as /resources/{key}. Optimizing the {key} away would lead
>>>>>> to a slightly unbalanced space:
>>>>>>
>>>>>> // GET the 1st resource
>>>>>> GET /resources/1
>>>>>> // Update the 1st resource
>>>>>> PUT /resources
>>>>>>  (the representation with the key)
>>>>>>
>>>>>> My opinion has always been that ultimately the more practical it is
>>>>>> the better as opposed to the purer the better. It might be 
>>>>>> reasonable
>>>>>> to support both styles:
>>>>>>
>>>>>> PUT /resources/1
>>>>>>
>>>>>> POST /resources
>>>>>>
>>>>>> as POST is usually deals with the collection of resources and I 
>>>>>> guess
>>>>>> it may be reasonable to suggest that POSTing to a collection which
>>>>>> already contains an element with the same key means the actual 
>>>>>> update.
>>>>>
>>>>> I'd agree to keep
>>>>>
>>>>> PUT /resources/1
>>>>>
>>>>> which definitely makes sense; I thought there was some "magic" JAX-RS
>>>>> annotation to identify an argument as request body so that I could 
>>>>> write
>>>>>
>>>>>       @PUT
>>>>>       @Path("{key}")
>>>>>       @Consumes({ MediaType.APPLICATION_XML,
>>>>> MediaType.APPLICATION_JSON })
>>>>>       void update(@BeanParam @RequestBody ResourceTO resourceTO);
>>>>>
>>>>> Given the considerations above, I'd say we'll probably leave things
>>>>> unchanged.
>>>>>
>>>>> Regards.
>>>>>
>>>>>> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>>>>>>> Hi,
>>>>>>> we have several "update" methods in our JAX-RS services, with 
>>>>>>> similar
>>>>>>> signature:
>>>>>>>
>>>>>>>      @PUT
>>>>>>>      @Path("{key}")
>>>>>>>      @Consumes({ MediaType.APPLICATION_XML,
>>>>>>> MediaType.APPLICATION_JSON })
>>>>>>>      void update(@NotNull @PathParam("key") String key, @NotNull
>>>>>>> ResourceTO resourceTO);
>>>>>>>
>>>>>>> For various reasons, the key value is already contained in the
>>>>>>> ResourceTO bean; this leads to kind of redundant invocations 
>>>>>>> like as
>>>>>>>
>>>>>>> resourceService.update(resourceTO.getKey(), resourceTO);
>>>>>>>
>>>>>>> I was wondering whether this situation can be improved by using
>>>>>>> @BeanParam:
>>>>>>>
>>>>>>>      void update(@BeanParam ResourceTO resourceTO);
>>>>>>>
>>>>>>> by annotating ResourceTO#setKey() with @Path("{key}").
>>>>>>>
>>>>>>> It seems that with such setup only "key" is evaluated, e.g. the
>>>>>>> rest of
>>>>>>> ResourceTO instance is left empty.
>>>>>>>
>>>>>>> Am I missing something? Any suggestion to fix the original problem?
>>>>>>>
>>>>>>> Thanks for your support.
>>>>>>> Regards.

-- 
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Involved at The Apache Software Foundation:
member, Syncope PMC chair, Cocoon PMC, Olingo PMC
http://people.apache.org/~ilgrosso/


Re: [JAX-RS] Best practice for update methods

Posted by Francesco Chicchiriccò <il...@apache.org>.
On 09/06/2015 15:17, Sergey Beryozkin wrote:
> Hi Francesco
> See https://issues.apache.org/jira/browse/CXF-6447,
>
> So you'd be able to optimize the signature if still preferred, the 
> server code would stay completely portable, though only CXF proxies 
> would likely to work with such signatures in the short term at least

Wow, cool stuff :-)

I'll check with CXF 3.1.2-SNAPSHOT and let you know how ti goes.

Thanks.

> On 08/06/15 10:43, Sergey Beryozkin wrote:
>> Sorry, that will not work with the proxies as they won't be able to
>> resolve the {key} :-), with webclients only...
>>
>> I wonder if we can explore your idea on the client side and try to
>> resolve a variable if the body bean is available...I'll try to
>> experiment a bit later on
>>
>> Thanks, Sergey
>>
>>
>> On 08/06/15 10:40, Sergey Beryozkin wrote:
>>> Hi Francesco,
>>>
>>> By the way, it is fine to have something like this:
>>>
>>> @PUT
>>> @Path("{key}")
>>> public void update(ResourceTo bean) {}
>>>
>>> That can actually be the optimal signature, if the bean contains the 
>>> key
>>> then it can be taken from the bean and if not - then from UriInfo by
>>> analyzing the path value. Often a Path variable is also represented
>>> with PathParam but it is not a requirement
>>>
>>> Cheers, Sergey
>>>
>>> On 08/06/15 10:32, Francesco Chicchiriccò wrote:
>>>> Hi Sergey,
>>>> thanks for your response.
>>>>
>>>> On 08/06/2015 11:16, Sergey Beryozkin wrote:
>>>>> Hi Francesco
>>>>>
>>>>> Sure, you can try:
>>>>>
>>>>> @PUT
>>>>> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>>>>> void update(@NotNull ResourceTO resourceTO);
>>>>>
>>>>> Omitting the extra @Path completely and getting the key out of
>>>>> ResourceTo bean:
>>>>>
>>>>> PUT /resources
>>>>>
>>>>> <Resource>
>>>>>   <key>1</key>
>>>>>   <!- the rest of the representation -->
>>>>> </Resource>
>>>>>
>>>>> given that the key is available there.
>>>>>
>>>>>
>>>>> That said, if we were to abstract away from the the redundant proxy
>>>>> code where the key is specified twice during the invocation, one can
>>>>> say PUT targets an individual resource representation which is indeed
>>>>> identified as /resources/{key}. Optimizing the {key} away would lead
>>>>> to a slightly unbalanced space:
>>>>>
>>>>> // GET the 1st resource
>>>>> GET /resources/1
>>>>> // Update the 1st resource
>>>>> PUT /resources
>>>>>  (the representation with the key)
>>>>>
>>>>> My opinion has always been that ultimately the more practical it is
>>>>> the better as opposed to the purer the better. It might be reasonable
>>>>> to support both styles:
>>>>>
>>>>> PUT /resources/1
>>>>>
>>>>> POST /resources
>>>>>
>>>>> as POST is usually deals with the collection of resources and I guess
>>>>> it may be reasonable to suggest that POSTing to a collection which
>>>>> already contains an element with the same key means the actual 
>>>>> update.
>>>>
>>>> I'd agree to keep
>>>>
>>>> PUT /resources/1
>>>>
>>>> which definitely makes sense; I thought there was some "magic" JAX-RS
>>>> annotation to identify an argument as request body so that I could 
>>>> write
>>>>
>>>>       @PUT
>>>>       @Path("{key}")
>>>>       @Consumes({ MediaType.APPLICATION_XML,
>>>> MediaType.APPLICATION_JSON })
>>>>       void update(@BeanParam @RequestBody ResourceTO resourceTO);
>>>>
>>>> Given the considerations above, I'd say we'll probably leave things
>>>> unchanged.
>>>>
>>>> Regards.
>>>>
>>>>> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>>>>>> Hi,
>>>>>> we have several "update" methods in our JAX-RS services, with 
>>>>>> similar
>>>>>> signature:
>>>>>>
>>>>>>      @PUT
>>>>>>      @Path("{key}")
>>>>>>      @Consumes({ MediaType.APPLICATION_XML,
>>>>>> MediaType.APPLICATION_JSON })
>>>>>>      void update(@NotNull @PathParam("key") String key, @NotNull
>>>>>> ResourceTO resourceTO);
>>>>>>
>>>>>> For various reasons, the key value is already contained in the
>>>>>> ResourceTO bean; this leads to kind of redundant invocations like as
>>>>>>
>>>>>> resourceService.update(resourceTO.getKey(), resourceTO);
>>>>>>
>>>>>> I was wondering whether this situation can be improved by using
>>>>>> @BeanParam:
>>>>>>
>>>>>>      void update(@BeanParam ResourceTO resourceTO);
>>>>>>
>>>>>> by annotating ResourceTO#setKey() with @Path("{key}").
>>>>>>
>>>>>> It seems that with such setup only "key" is evaluated, e.g. the
>>>>>> rest of
>>>>>> ResourceTO instance is left empty.
>>>>>>
>>>>>> Am I missing something? Any suggestion to fix the original problem?
>>>>>>
>>>>>> Thanks for your support.
>>>>>> Regards.

-- 
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Involved at The Apache Software Foundation:
member, Syncope PMC chair, Cocoon PMC, Olingo PMC
http://people.apache.org/~ilgrosso/


Re: [JAX-RS] Best practice for update methods

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Francesco
See https://issues.apache.org/jira/browse/CXF-6447,

So you'd be able to optimize the signature if still preferred, the 
server code would stay completely portable, though only CXF proxies 
would likely to work with such signatures in the short term at least

Thanks, Sergey
On 08/06/15 10:43, Sergey Beryozkin wrote:
> Sorry, that will not work with the proxies as they won't be able to
> resolve the {key} :-), with webclients only...
>
> I wonder if we can explore your idea on the client side and try to
> resolve a variable if the body bean is available...I'll try to
> experiment a bit later on
>
> Thanks, Sergey
>
>
> On 08/06/15 10:40, Sergey Beryozkin wrote:
>> Hi Francesco,
>>
>> By the way, it is fine to have something like this:
>>
>> @PUT
>> @Path("{key}")
>> public void update(ResourceTo bean) {}
>>
>> That can actually be the optimal signature, if the bean contains the key
>> then it can be taken from the bean and if not - then from UriInfo by
>> analyzing the path value. Often a Path variable is also represented
>> with PathParam but it is not a requirement
>>
>> Cheers, Sergey
>>
>> On 08/06/15 10:32, Francesco Chicchiriccò wrote:
>>> Hi Sergey,
>>> thanks for your response.
>>>
>>> On 08/06/2015 11:16, Sergey Beryozkin wrote:
>>>> Hi Francesco
>>>>
>>>> Sure, you can try:
>>>>
>>>> @PUT
>>>> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>>>> void update(@NotNull ResourceTO resourceTO);
>>>>
>>>> Omitting the extra @Path completely and getting the key out of
>>>> ResourceTo bean:
>>>>
>>>> PUT /resources
>>>>
>>>> <Resource>
>>>>   <key>1</key>
>>>>   <!- the rest of the representation -->
>>>> </Resource>
>>>>
>>>> given that the key is available there.
>>>>
>>>>
>>>> That said, if we were to abstract away from the the redundant proxy
>>>> code where the key is specified twice during the invocation, one can
>>>> say PUT targets an individual resource representation which is indeed
>>>> identified as /resources/{key}. Optimizing the {key} away would lead
>>>> to a slightly unbalanced space:
>>>>
>>>> // GET the 1st resource
>>>> GET /resources/1
>>>> // Update the 1st resource
>>>> PUT /resources
>>>>  (the representation with the key)
>>>>
>>>> My opinion has always been that ultimately the more practical it is
>>>> the better as opposed to the purer the better. It might be reasonable
>>>> to support both styles:
>>>>
>>>> PUT /resources/1
>>>>
>>>> POST /resources
>>>>
>>>> as POST is usually deals with the collection of resources and I guess
>>>> it may be reasonable to suggest that POSTing to a collection which
>>>> already contains an element with the same key means the actual update.
>>>
>>> I'd agree to keep
>>>
>>> PUT /resources/1
>>>
>>> which definitely makes sense; I thought there was some "magic" JAX-RS
>>> annotation to identify an argument as request body so that I could write
>>>
>>>       @PUT
>>>       @Path("{key}")
>>>       @Consumes({ MediaType.APPLICATION_XML,
>>> MediaType.APPLICATION_JSON })
>>>       void update(@BeanParam @RequestBody ResourceTO resourceTO);
>>>
>>> Given the considerations above, I'd say we'll probably leave things
>>> unchanged.
>>>
>>> Regards.
>>>
>>>> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>>>>> Hi,
>>>>> we have several "update" methods in our JAX-RS services, with similar
>>>>> signature:
>>>>>
>>>>>      @PUT
>>>>>      @Path("{key}")
>>>>>      @Consumes({ MediaType.APPLICATION_XML,
>>>>> MediaType.APPLICATION_JSON })
>>>>>      void update(@NotNull @PathParam("key") String key, @NotNull
>>>>> ResourceTO resourceTO);
>>>>>
>>>>> For various reasons, the key value is already contained in the
>>>>> ResourceTO bean; this leads to kind of redundant invocations like as
>>>>>
>>>>> resourceService.update(resourceTO.getKey(), resourceTO);
>>>>>
>>>>> I was wondering whether this situation can be improved by using
>>>>> @BeanParam:
>>>>>
>>>>>      void update(@BeanParam ResourceTO resourceTO);
>>>>>
>>>>> by annotating ResourceTO#setKey() with @Path("{key}").
>>>>>
>>>>> It seems that with such setup only "key" is evaluated, e.g. the
>>>>> rest of
>>>>> ResourceTO instance is left empty.
>>>>>
>>>>> Am I missing something? Any suggestion to fix the original problem?
>>>>>
>>>>> Thanks for your support.
>>>>> Regards.
>>>
>>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: [JAX-RS] Best practice for update methods

Posted by Sergey Beryozkin <sb...@gmail.com>.
Sorry, that will not work with the proxies as they won't be able to 
resolve the {key} :-), with webclients only...

I wonder if we can explore your idea on the client side and try to 
resolve a variable if the body bean is available...I'll try to 
experiment a bit later on

Thanks, Sergey


On 08/06/15 10:40, Sergey Beryozkin wrote:
> Hi Francesco,
>
> By the way, it is fine to have something like this:
>
> @PUT
> @Path("{key}")
> public void update(ResourceTo bean) {}
>
> That can actually be the optimal signature, if the bean contains the key
> then it can be taken from the bean and if not - then from UriInfo by
> analyzing the path value. Often a Path variable is also represented
> with PathParam but it is not a requirement
>
> Cheers, Sergey
>
> On 08/06/15 10:32, Francesco Chicchiriccò wrote:
>> Hi Sergey,
>> thanks for your response.
>>
>> On 08/06/2015 11:16, Sergey Beryozkin wrote:
>>> Hi Francesco
>>>
>>> Sure, you can try:
>>>
>>> @PUT
>>> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>>> void update(@NotNull ResourceTO resourceTO);
>>>
>>> Omitting the extra @Path completely and getting the key out of
>>> ResourceTo bean:
>>>
>>> PUT /resources
>>>
>>> <Resource>
>>>   <key>1</key>
>>>   <!- the rest of the representation -->
>>> </Resource>
>>>
>>> given that the key is available there.
>>>
>>>
>>> That said, if we were to abstract away from the the redundant proxy
>>> code where the key is specified twice during the invocation, one can
>>> say PUT targets an individual resource representation which is indeed
>>> identified as /resources/{key}. Optimizing the {key} away would lead
>>> to a slightly unbalanced space:
>>>
>>> // GET the 1st resource
>>> GET /resources/1
>>> // Update the 1st resource
>>> PUT /resources
>>>  (the representation with the key)
>>>
>>> My opinion has always been that ultimately the more practical it is
>>> the better as opposed to the purer the better. It might be reasonable
>>> to support both styles:
>>>
>>> PUT /resources/1
>>>
>>> POST /resources
>>>
>>> as POST is usually deals with the collection of resources and I guess
>>> it may be reasonable to suggest that POSTing to a collection which
>>> already contains an element with the same key means the actual update.
>>
>> I'd agree to keep
>>
>> PUT /resources/1
>>
>> which definitely makes sense; I thought there was some "magic" JAX-RS
>> annotation to identify an argument as request body so that I could write
>>
>>       @PUT
>>       @Path("{key}")
>>       @Consumes({ MediaType.APPLICATION_XML,
>> MediaType.APPLICATION_JSON })
>>       void update(@BeanParam @RequestBody ResourceTO resourceTO);
>>
>> Given the considerations above, I'd say we'll probably leave things
>> unchanged.
>>
>> Regards.
>>
>>> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>>>> Hi,
>>>> we have several "update" methods in our JAX-RS services, with similar
>>>> signature:
>>>>
>>>>      @PUT
>>>>      @Path("{key}")
>>>>      @Consumes({ MediaType.APPLICATION_XML,
>>>> MediaType.APPLICATION_JSON })
>>>>      void update(@NotNull @PathParam("key") String key, @NotNull
>>>> ResourceTO resourceTO);
>>>>
>>>> For various reasons, the key value is already contained in the
>>>> ResourceTO bean; this leads to kind of redundant invocations like as
>>>>
>>>> resourceService.update(resourceTO.getKey(), resourceTO);
>>>>
>>>> I was wondering whether this situation can be improved by using
>>>> @BeanParam:
>>>>
>>>>      void update(@BeanParam ResourceTO resourceTO);
>>>>
>>>> by annotating ResourceTO#setKey() with @Path("{key}").
>>>>
>>>> It seems that with such setup only "key" is evaluated, e.g. the rest of
>>>> ResourceTO instance is left empty.
>>>>
>>>> Am I missing something? Any suggestion to fix the original problem?
>>>>
>>>> Thanks for your support.
>>>> Regards.
>>
>


Re: [JAX-RS] Best practice for update methods

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Francesco,

By the way, it is fine to have something like this:

@PUT
@Path("{key}")
public void update(ResourceTo bean) {}

That can actually be the optimal signature, if the bean contains the key 
then it can be taken from the bean and if not - then from UriInfo by 
analyzing the path value. Often a Path variable is also represented
with PathParam but it is not a requirement

Cheers, Sergey

On 08/06/15 10:32, Francesco Chicchiriccò wrote:
> Hi Sergey,
> thanks for your response.
>
> On 08/06/2015 11:16, Sergey Beryozkin wrote:
>> Hi Francesco
>>
>> Sure, you can try:
>>
>> @PUT
>> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>> void update(@NotNull ResourceTO resourceTO);
>>
>> Omitting the extra @Path completely and getting the key out of
>> ResourceTo bean:
>>
>> PUT /resources
>>
>> <Resource>
>>   <key>1</key>
>>   <!- the rest of the representation -->
>> </Resource>
>>
>> given that the key is available there.
>>
>>
>> That said, if we were to abstract away from the the redundant proxy
>> code where the key is specified twice during the invocation, one can
>> say PUT targets an individual resource representation which is indeed
>> identified as /resources/{key}. Optimizing the {key} away would lead
>> to a slightly unbalanced space:
>>
>> // GET the 1st resource
>> GET /resources/1
>> // Update the 1st resource
>> PUT /resources
>>  (the representation with the key)
>>
>> My opinion has always been that ultimately the more practical it is
>> the better as opposed to the purer the better. It might be reasonable
>> to support both styles:
>>
>> PUT /resources/1
>>
>> POST /resources
>>
>> as POST is usually deals with the collection of resources and I guess
>> it may be reasonable to suggest that POSTing to a collection which
>> already contains an element with the same key means the actual update.
>
> I'd agree to keep
>
> PUT /resources/1
>
> which definitely makes sense; I thought there was some "magic" JAX-RS
> annotation to identify an argument as request body so that I could write
>
>       @PUT
>       @Path("{key}")
>       @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>       void update(@BeanParam @RequestBody ResourceTO resourceTO);
>
> Given the considerations above, I'd say we'll probably leave things
> unchanged.
>
> Regards.
>
>> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>>> Hi,
>>> we have several "update" methods in our JAX-RS services, with similar
>>> signature:
>>>
>>>      @PUT
>>>      @Path("{key}")
>>>      @Consumes({ MediaType.APPLICATION_XML,
>>> MediaType.APPLICATION_JSON })
>>>      void update(@NotNull @PathParam("key") String key, @NotNull
>>> ResourceTO resourceTO);
>>>
>>> For various reasons, the key value is already contained in the
>>> ResourceTO bean; this leads to kind of redundant invocations like as
>>>
>>> resourceService.update(resourceTO.getKey(), resourceTO);
>>>
>>> I was wondering whether this situation can be improved by using
>>> @BeanParam:
>>>
>>>      void update(@BeanParam ResourceTO resourceTO);
>>>
>>> by annotating ResourceTO#setKey() with @Path("{key}").
>>>
>>> It seems that with such setup only "key" is evaluated, e.g. the rest of
>>> ResourceTO instance is left empty.
>>>
>>> Am I missing something? Any suggestion to fix the original problem?
>>>
>>> Thanks for your support.
>>> Regards.
>


Re: [JAX-RS] Best practice for update methods

Posted by Francesco Chicchiriccò <il...@apache.org>.
Hi Sergey,
thanks for your response.

On 08/06/2015 11:16, Sergey Beryozkin wrote:
> Hi Francesco
>
> Sure, you can try:
>
> @PUT
> @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
> void update(@NotNull ResourceTO resourceTO);
>
> Omitting the extra @Path completely and getting the key out of 
> ResourceTo bean:
>
> PUT /resources
>
> <Resource>
>   <key>1</key>
>   <!- the rest of the representation -->
> </Resource>
>
> given that the key is available there.
>
>
> That said, if we were to abstract away from the the redundant proxy 
> code where the key is specified twice during the invocation, one can 
> say PUT targets an individual resource representation which is indeed 
> identified as /resources/{key}. Optimizing the {key} away would lead 
> to a slightly unbalanced space:
>
> // GET the 1st resource
> GET /resources/1
> // Update the 1st resource
> PUT /resources
>  (the representation with the key)
>
> My opinion has always been that ultimately the more practical it is 
> the better as opposed to the purer the better. It might be reasonable 
> to support both styles:
>
> PUT /resources/1
>
> POST /resources
>
> as POST is usually deals with the collection of resources and I guess 
> it may be reasonable to suggest that POSTing to a collection which 
> already contains an element with the same key means the actual update.

I'd agree to keep

PUT /resources/1

which definitely makes sense; I thought there was some "magic" JAX-RS 
annotation to identify an argument as request body so that I could write

      @PUT
      @Path("{key}")
      @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
      void update(@BeanParam @RequestBody ResourceTO resourceTO);

Given the considerations above, I'd say we'll probably leave things 
unchanged.

Regards.

> On 08/06/15 07:05, Francesco Chicchiriccò wrote:
>> Hi,
>> we have several "update" methods in our JAX-RS services, with similar
>> signature:
>>
>>      @PUT
>>      @Path("{key}")
>>      @Consumes({ MediaType.APPLICATION_XML, 
>> MediaType.APPLICATION_JSON })
>>      void update(@NotNull @PathParam("key") String key, @NotNull
>> ResourceTO resourceTO);
>>
>> For various reasons, the key value is already contained in the
>> ResourceTO bean; this leads to kind of redundant invocations like as
>>
>> resourceService.update(resourceTO.getKey(), resourceTO);
>>
>> I was wondering whether this situation can be improved by using 
>> @BeanParam:
>>
>>      void update(@BeanParam ResourceTO resourceTO);
>>
>> by annotating ResourceTO#setKey() with @Path("{key}").
>>
>> It seems that with such setup only "key" is evaluated, e.g. the rest of
>> ResourceTO instance is left empty.
>>
>> Am I missing something? Any suggestion to fix the original problem?
>>
>> Thanks for your support.
>> Regards.

-- 
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Involved at The Apache Software Foundation:
member, Syncope PMC chair, Cocoon PMC, Olingo PMC
http://people.apache.org/~ilgrosso/


Re: [JAX-RS] Best practice for update methods

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Francesco

Sure, you can try:

@PUT
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
void update(@NotNull ResourceTO resourceTO);

Omitting the extra @Path completely and getting the key out of 
ResourceTo bean:

PUT /resources

<Resource>
   <key>1</key>
   <!- the rest of the representation -->
</Resource>

given that the key is available there.


That said, if we were to abstract away from the the redundant proxy code 
where the key is specified twice during the invocation, one can say PUT 
targets an individual resource representation which is indeed identified 
as /resources/{key}. Optimizing the {key} away would lead to a slightly 
unbalanced space:

// GET the 1st resource
GET /resources/1
// Update the 1st resource
PUT /resources
  (the representation with the key)

My opinion has always been that ultimately the more practical it is the 
better as opposed to the purer the better. It might be reasonable to 
support both styles:

PUT /resources/1

POST /resources

as POST is usually deals with the collection of resources and I guess it 
may be reasonable to suggest that POSTing to a collection which already 
contains an element with the same key means the actual update.

It can become complex trying to figure out the perfect combination :-)


Cheers, Sergey




On 08/06/15 07:05, Francesco Chicchiriccò wrote:
> Hi,
> we have several "update" methods in our JAX-RS services, with similar
> signature:
>
>      @PUT
>      @Path("{key}")
>      @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
>      void update(@NotNull @PathParam("key") String key, @NotNull
> ResourceTO resourceTO);
>
> For various reasons, the key value is already contained in the
> ResourceTO bean; this leads to kind of redundant invocations like as
>
> resourceService.update(resourceTO.getKey(), resourceTO);
>
> I was wondering whether this situation can be improved by using @BeanParam:
>
>      void update(@BeanParam ResourceTO resourceTO);
>
> by annotating ResourceTO#setKey() with @Path("{key}").
>
> It seems that with such setup only "key" is evaluated, e.g. the rest of
> ResourceTO instance is left empty.
>
> Am I missing something? Any suggestion to fix the original problem?
>
> Thanks for your support.
> Regards.
>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com