Hi, I recently spent some time on implementing JSR-311 (JAX-RS: Java API for 
RESTful Web Services [1]) in CXF. The prototype code can be checked out from 
branch https://svn.apache.org/repos/asf/incubator/cxf/branches/jliu. As this is 
still in a prototype phase, please don’t mind uncleared warnings, funny hacked 
methods etc. Any comments or feedbacks will be highly appreciated.

When I first started looking into the implementation, I actually have three 
different design choices:

The first approach is to implement JAX-RS in CXF similar to Jersey [2], using 
the JAX-WS Provider API as a proxy to direct request from CXF runtime to JAX-RS 
runtime. This might be the least intrusive approach as from the CXF runtime’s 
point of view, the JAX-RS runtime is really just an application sitting on top 
of CXF. On the other hand, less intrusion means less control. Taking this 
approach, for example, the only information CXF runtime knows about the JAX-RS 
service is that it has a method exposed as invoke(T). This may gives us 
difficulties later on when we bring in management capabilities or introduce a 
service description language like WADL. Another problem is a potential 
performance penalty. Depends on the specific JAX-WS implementation, there is 
always an extra time spent on transforming input stream to the T in the 
Provider.invoke(T). 

The second and the third approach are both implementing JAX-RS in CXF core. 
What distinguished them from each other is whether or not to implement JAX-RS 
based on existing CXF API models. The CXF API models I referred to are frontend 
APIs such as serviceFactoryBean/serverFactoryBean/Endpoint/EndpointInfo, 
Binding APIs, DataBinding APIs, Transport APIs and service model etc. As I 
mentioned early, the major problem with these CXF APIs is they are very 
WSDL-centric. To get around this, we can either refactor CXF APIs so that at 
least the top abstract layer is suitable for both WSDL-based services and 
non-WSDL-based services. Or we can start off a new set of APIs for 
non-WSDL-based services and built JAX-RS implementation on top of them.  My 
prototype implementation takes the former approach, can be briefed as below:

1. Refactored CXF APIs, so that AbstractServiceFactoryBean and 
AbstractEndpointFactory become the base classes that are neutral to both 
WSDL-based services and non-WSDL-based services. Also refactor Service 
interface so that it can represent both WSDL service model and non-WSDL service 
model. The service model for JAX-RS is pretty simple, it consists of resource 
classes and each resource class consists of a set of resource methods. 

2. JAXRSServiceFactoryBean extended from AbstractServiceFactoryBean, is 
responsible for the creation of service model, data binding etc.

3. JAXRSServerFactoryBean extended from AbstractEndpointFactory, is responsible 
for creating EndpointInfo, Endpoint, BindingFactory, ServerImpl etc.

4. Start a JAX-RS service would look very similar to Simple or JAX-WS frontend:

        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
        sf.setResourceClasses(BookStore.class);
        sf.setBindingId(JAXRSBindingFactory.JAXRS_BINDING_ID);
        sf.setAddress("http://localhost:9080/xml/";);

        sf.create();   

I have created a simple bookstore sample, which is located under 
\systests\src\test\java\org\apache\cxf\systest\jaxrs. At the moment, the JAX-RS 
implementation does not support sub-resource locators yet, thus this service 
can only serve services for the following URLs:

http://localhost:9080/xml/bookstore  return all books
http://localhost:9080/xml/bookstore/123  return book 123


[1]. JSR-311 Spec: https://jsr311.dev.java.net/
[2]. Jersey: https://jersey.dev.java.net/

Cheers,
Jervis
 



----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Reply via email to