You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by jeff fitzgerald <je...@gmail.com> on 2013/04/22 16:32:55 UTC

Restful services without annotations

I've been playing around with a dynamic service/plugin model that I could
register with CXF that would not require any annotations (based on some of
the docs I read here:
http://cxf.apache.org/docs/jax-rs-advanced-features.html).

I started by defining a Generic Service that had a method per HTTP
operation.

public class GenericService
{
    Response get();
    Response put(Object content);
    Response post(Object content);
    Response delete();
}

Then, I was hoping I could define a list of resources in the model file,
and map each operation within each resource to one of the methods in the
generic service.

<model xmlns="http://cxf.apache.org/jaxrs">
    <resource name="com.example.GenericService" path="bookstore">
        <operation name="get" verb="GET" path="/books"
produces="application/xml"/>
        <operation name="get" verb="GET" path="/books/{id}">
            <param name="id" type="PATH"/>
        </operation>
    </resource>
    <resource name="com.example.GenericService" path="bank">
        <operation name="get" verb="GET" path="/money"/>
        <operation name="put" verb="PUT" path="/money"
consumes="application/xml">
            <param name="content" type="REQUEST_BODY"/>
        </operation>
    </resource>
</model>

However, I ran into a couple of problems.

Based on the example above, in the bookstore resource, only the second GET
operation is registered; the first one returns 404. Also, if I try to
define another resource with a different path but using the same generic
service, the bookstore example above would return 404, and only the bank
endpoint would be available.

I'm guessing the resources are store in some sort of map, and they must be
using the same key (the resource name rather than the path).

Is there any way for me to define a generic resource/service class to
process more than one path?

Thanks,

Fitz

Re: Restful services without annotations

Posted by Sergey Beryozkin <sb...@gmail.com>.
One thing I forgot to mention, if you do need to have the same class 
(without annotations in this case) supporting multiple paths, example,

/a/b/price
/bank/price

where 'price' maps to say GenericService.get

then it is better to support it a higher level, one option is to have 
two jaxrs endpoints sharing the same GenericService instance, but the 
first having "/a/b" address, the 2nd - "/bank". Or have a single 
endpoint with "/" but two CXFServlets with "/a/b/*" & "/bank/*" URL 
patterns

Sergey

On 22/04/13 15:48, Sergey Beryozkin wrote:
> Hi
> On 22/04/13 15:32, jeff fitzgerald wrote:
>> I've been playing around with a dynamic service/plugin model that I could
>> register with CXF that would not require any annotations (based on
>> some of
>> the docs I read here:
>> http://cxf.apache.org/docs/jax-rs-advanced-features.html).
>>
>> I started by defining a Generic Service that had a method per HTTP
>> operation.
>>
>> public class GenericService
>> {
>> Response get();
>> Response put(Object content);
>> Response post(Object content);
>> Response delete();
>> }
>>
>> Then, I was hoping I could define a list of resources in the model file,
>> and map each operation within each resource to one of the methods in the
>> generic service.
>>
>> <model xmlns="http://cxf.apache.org/jaxrs">
>> <resource name="com.example.GenericService" path="bookstore">
>> <operation name="get" verb="GET" path="/books"
>> produces="application/xml"/>
>> <operation name="get" verb="GET" path="/books/{id}">
>> <param name="id" type="PATH"/>
>> </operation>
>> </resource>
>
> Would you like to use the same operation to handle both /books &
> /books/{id} ? If so then the only (JAX-RS compliant) way to do it is to
> have a custom regular expression, example,
>
> <resource name="com.example.GenericService" path="bookstore">
> <operation name="get" verb="GET" path="/books/{id:.*}"
> produces="application/xml"/>
> </resource>
>
> something like that
>> <resource name="com.example.GenericService" path="bank">
>> <operation name="get" verb="GET" path="/money"/>
>> <operation name="put" verb="PUT" path="/money"
>> consumes="application/xml">
>> <param name="content" type="REQUEST_BODY"/>
>> </operation>
>> </resource>
>> </model>
>>
>> However, I ran into a couple of problems.
>>
>> Based on the example above, in the bookstore resource, only the second
>> GET
>> operation is registered; the first one returns 404.
>
> See the comment above...
>
>> Also, if I try to
>> define another resource with a different path but using the same generic
>> service, the bookstore example above would return 404, and only the bank
>> endpoint would be available.
>>
>> I'm guessing the resources are store in some sort of map, and they
>> must be
>> using the same key (the resource name rather than the path).
>>
>> Is there any way for me to define a generic resource/service class to
>> process more than one path?
>>
>
> Do you actually need com.example.GenericService to handle both
>
> GET /bookstore/books
> and
> GET /bank/money
>
> and moreover, using the same method ? I guess that was just a test, do
> you have a concrete requirement where something like that is required ?
>
> Thanks, Sergey
>
>
>> Thanks,
>>
>> Fitz
>>
>


-- 
Sergey Beryozkin

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

Blog: http://sberyozkin.blogspot.com

Re: Restful services without annotations

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 22/04/13 15:32, jeff fitzgerald wrote:
> I've been playing around with a dynamic service/plugin model that I could
> register with CXF that would not require any annotations (based on some of
> the docs I read here:
> http://cxf.apache.org/docs/jax-rs-advanced-features.html).
>
> I started by defining a Generic Service that had a method per HTTP
> operation.
>
> public class GenericService
> {
>      Response get();
>      Response put(Object content);
>      Response post(Object content);
>      Response delete();
> }
>
> Then, I was hoping I could define a list of resources in the model file,
> and map each operation within each resource to one of the methods in the
> generic service.
>
> <model xmlns="http://cxf.apache.org/jaxrs">
>      <resource name="com.example.GenericService" path="bookstore">
>          <operation name="get" verb="GET" path="/books"
> produces="application/xml"/>
>          <operation name="get" verb="GET" path="/books/{id}">
>              <param name="id" type="PATH"/>
>          </operation>
>      </resource>

Would you like to use the same operation to handle both /books & 
/books/{id} ? If so then the only (JAX-RS compliant) way to do it is to 
have a custom regular expression, example,

<resource name="com.example.GenericService" path="bookstore">
  <operation name="get" verb="GET" path="/books/{id:.*}"
             produces="application/xml"/>
</resource>

something like that
>      <resource name="com.example.GenericService" path="bank">
>          <operation name="get" verb="GET" path="/money"/>
>          <operation name="put" verb="PUT" path="/money"
> consumes="application/xml">
>              <param name="content" type="REQUEST_BODY"/>
>          </operation>
>      </resource>
> </model>
>
> However, I ran into a couple of problems.
>
> Based on the example above, in the bookstore resource, only the second GET
> operation is registered; the first one returns 404.

See the comment above...

> Also, if I try to
> define another resource with a different path but using the same generic
> service, the bookstore example above would return 404, and only the bank
> endpoint would be available.
>
> I'm guessing the resources are store in some sort of map, and they must be
> using the same key (the resource name rather than the path).
>
> Is there any way for me to define a generic resource/service class to
> process more than one path?
>

Do you actually need com.example.GenericService to handle both

GET /bookstore/books
and
GET /bank/money

and moreover, using the same method ? I guess that was just a test, do 
you have a concrete requirement where something like that is required ?

Thanks, Sergey


> Thanks,
>
> Fitz
>