Exposing RESTful interface with Mule pt.2
In previous part of this article I’ve presented two ways of building REST API on Mule ESB: using Mule REST Module and handling HTTP properties manually.
This time I want to present achieving the same result using Mule Jersey Module with addition of
Component Bindings - feature of Mule, which enables us to leave Java and go back to Mule flow processing.
Presented example was tested against Mule ESB 3.4.0 EE.
3. Jersey REST
Flow overview:
Unfortunately, not much to see in this graphical overview - devil is in the details :)
Jersey REST Component is the official recommendation for exposing REST Services on Mule ESB. Usually, this reference implementation of JAX-RS would be everything we need to achieve the goal. However, in terms of Mule, it ties us heavily to Java code, which is not what we are especially looking for. To overcome this we can use Component Bindings.
Let’s go back to our example. Staring with the simple Jersey service class:
|
|
Nothing fancy here. JAX-RS plain and simple. Interesting part is the FlowProcessing interface. It looks like it’s wrapping whole business logic processing. By using Component Bindings we can make any Mule’s outbound endpoint behave as an implementation of that interface. Hence, we can make use of VM endpoints and move the processing from Java back to Mule flows:
|
|
As seen above, everything we need to make it work is to provide binding element specifying the interface, interface’s method and outbound endpoint, which should be called. Few things to remember:
- Don’t forget to write setter for the interface in the Jersey class.
- Make sure that request and response of the interface and endpoint matches
- It is possible to have the method return MuleMessage. It lets Java component have access to whole message, not only payload.
Flows with the “business logic” for POST and GET methods processing are described below:
|
|
Input parameters of the FlowProcessing interface methods comes in the Mule flows as an Object array. We can map them into Mule parameters by writting and setting global transformer:
|
|
and reusing it in the flows:
|
|
PopulateVariables Java transformer:
|
|
We have everything in place to make it work. One thing I don’t like is that Jersey for requests with URL not met is returning 404 HTTP status (Not Found). I find 400 status (Bad Request) more appropriate in such case and I’d like to keep 404 reserved for situations where URL was met, but resource was not found. Satysfying that requirement is fairly simple. We need to add a custom exception mapper in Jersey definition:
|
|
with implementation:
|
|
Note: It is possible to catch exceptions thrown in the binded outbound endpoints. To make that possible we just need to declare exception in binding interface method.
To test described solution I used the same set of tests as in previous post. However I was having problems testing successful scenarios using MUnit:
It seems that muleContext is not propagated correctly with MUnit and reflective proxy classes. Switching test class to use ‘official’ FunctionalTestCase instead of MUnit worked like a charm.
Full example at GitHub: JerseyREST
That were all the solutions for exposing REST Services I can think of.
In my work project, I’m using the REST Module and it’s doing its job well. Thus, if you want build REST API and use all of the nifty Mule features I would suggest going with the Router Module.
If you prefer to be more Java-centric, make use of Mule for handling integration matter only or to use Mule flows to a smaller extent then Jersey approach will fit in.
For more information about Component Bindings I encourage you to read Mule’s well-written blog post explaining the feature.