Friday, September 26, 2008

RESTful Web Services with Apache Axis2

RESTful Web Services with Apache Axis2 is powered by the WSDL 2.0 HTTPBinding, hence as of now (1.4.1 release of Axis2) users need to deploy there services using WSDL 2.0 to write truly RESTfull services in Axis2. I agree that there aren't too many people who are familiar with WSDL 2.0. Therefore I put together an article that helps you through the process of taking your Java code, generating a WSDL 2.0 from it and hand editing it to suit your needs. The article "RESTful Web Services with Apache Axis2" is now available on the WSO2 oxygen tank.

I plan on making it simpler to author RESTfull services in Axis2 in future.

6 comments:

Tammo said...

Hi Keith,

nice article, thanks. I'd be interested in your definition of "RESTful". In my opinion, it is not sufficient to expose methods under a given URI and a predefined HTTP verb. REST is IMO more about exposing state than functionality encapsulated in a single method.

For instance, how does Axis2 support caching, which is very important in RESTful architectures? Can I poll for a certain resource without invoking the business logic in the method behind the (resource, verb) tuple? How does Axis2 support long-running processing? Can it create a (temporary) resource, redirecting the client to it and stores the result of the processing there once it's finished? I also did not find any hint on how hyperlinks are supported.

I think there are still a few bricks missing to fully support REST, i.e. its philosophy. Actually, I believe that SOA and ROA are fundamentally different, in this respect I wonder how easy a framework for service-orientation can be transformed into a multi-purpose platform (which would be a very cool thing indeed).

Thanks,
Tammo

Keith Chapman said...

Hi Tammo,

Nice to hear that you found the article useful.

We have implemented caching for Axis2 in the form of a Axis2 module. This is available in the WSO2 Data Services release (You should be able to use it with Axis2 as well provided that you write your own caching policy). It contains a simple UI for configuring caching policy. (I will put a separate post on how caching can be configured).

What do you mean by How does Axis2 support long-running processing?

Regarding storing state, I'm not sure whether I understood your question correctly. But you could do it using Axis2 Sessions. Where you store the state in the session (Probably transport session which would map to http session when the http transport is used).

There is no explicit support for hyperlinks. But as my example shows invoking StudentService/students via a GET would return the links to the actual students. Invoking these links would return the student details.

Tammo said...

Hi Keith,

thanks for your answer. I'm looking forward to your article about the caching module. Would this also support cache invalidation through the application? For instance I'd like to use the observer pattern to notify the cache layer when specific parts of my data (in this case resources) have been updated in order to invalidate the cache. This should be then reflected in the cache-related HTTP headers for GET and HEAD requests.

Regarding a long-running execution of a service: HTTP has some limitations when it comes to data processing that lasts longer than XX seconds as you then may run into a time-out. In this case you can exploit the HTTP protocol for deferred processing which means that you POST your request to a resource and the server answers immediately with a "201 Created" and the URL where the result will be eventually available. A client can now poll until the request has been processed and the data is stored there. This kind of asynchrony helps to model/implement long-running things in REST. The actually processing might be even a nightly batch job.
See here for an example.

Anonymous said...
This comment has been removed by a blog administrator.
Lorenzo Dee said...

Hi Keith,

Thanks for that nice article. I've tried your sample, and it works nicely for REST (with HTTP binding only). I could get WSDLs via ?wsdl and ?wsdl2.

I noticed that you left out the SOAP bindings (for clarity), since you were talking about REST.

When I added the SOAP 1.1 and 1.2 bindings to the WSDL and deploy StudentService.aar, I could no longer get the WSDL 1.1 to be auto-generated via the URL StudentService?wsdl. What can I do to make that work?

Using StudentService?wsdl2 still works and returns a WSDL v2. But I couldn't get the WSDL v1.x. Is this a limitation of Axis2 1.5.x?

Thanks in advance.

Lorenzo Dee said...

It's me again.

I tried to use HTTP PUT (by using curl) to invoke the addStudent() method. My request body contains:

<student xmlns="http://axis2.apache.org">
    <name>Dee</name>
    <age>21</age>
</student>

The first time I try it, I get the message indicating that a Student with a "null" name was added. This doesn't seem right. I added some debug statements, and it shows that the name and age properties of the Student object are both uninitialized. What did I miss here? What configuration should I add/change to ask axis2 to populate a Student object with the HTTP body?

Thanks again in advance.