Overview
The Restlet project is a framework for building and consuming RESTful services.
The Mule Restlet connector integrates with Restlet to provide:
- The ability to route messages based on URI templates and the HTTP method being accessed.
- The ability to embed Restlets inside Mule
- The ability to use the Restlet Client API over Mule.
In addition to the documentation below, it is highly recommended that you read the Restlet documentation as well.
Classpath Settings
Currently the Restlet connector depends on Mule 2.1.0.
Mule Standalone
To set up the Mule classpath for the Restlet connector, you must first download the Mule Restlet distribution. Simply take all the JARs inside the distribution and put them in MULE_HOME/lib/user.
Maven
If you are using Maven, you can use the MuleForge repositories and add a dependency the Restlet conncetor. First add the MuleForge repository to your POM:
<repositories>
<repository>
<id>muleforge</id>
<name>MuleForge Repository</name>
<url>http://repository.muleforge.org</url>
</repository>
</repositories>
Then add the dependency:
<dependencies>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-restlet</artifactId>
<version>1.1.3</version>
</dependency>
</dependencies>
Configuration
The configuration snippets below all depend on the Restlet namespace. Here is an example of how to declare it inside your configuration file:
<mule xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mulesource.org/schema/mule/core/2.1"
xmlns:restlet="http://www.mulesource.org/schema/mule/restlet/2.1"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.mulesource.org/schema/mule/core/2.1 http://www.mulesource.org/schema/mule/core/2.1/mule.xsd
http://www.mulesource.org/schema/mule/restlet/2.1 http://www.mulesource.org/schema/mule/restlet/2.1/mule-restlet.xsd
">
... insert your configuration here
</mule>
URI Template Routing
The URI template routing allows you to use URI templates to route messages inside Mule.
URI templates are a way to match URIs. For example given the URI template "/orders/{orderId}" URIs of the form "/order/123" would match it. The text in between the curly brackets is a variable, in this case "orderId" is the variable name. It can be useful for extracting information from the URI as we'll see below.
Lets look at a simple example of how you can use URI templates to route different HTTP requests to different VM queues:
<service name="customerService">
<inbound>
<inbound-endpoint address="http://localhost:63080" remoteSync="true" />
</inbound>
<outbound>
<filtering-router>
<outbound-endpoint address="vm://orderQueue"/>
<restlet:uri-template-filter pattern="/orders/{orderId}"/>
</filtering-router>
<filtering-router>
<outbound-endpoint address="vm://userQueue"/>
<restlet:uri-template-filter pattern="/users" />
</filtering-router>
</outbound>
</service>
In this example, we're routing URIs of the form "/orders/{orderId}" to the orderQueue and URIs of the form "/users" to the userQueue. This takes advantage of the Mule filtering router which means you can use more advanced expressions as well. Here's an example which matches several URIs via an <or> filter.
<filtering-router>
<outbound-endpoint address="vm://userQueue"/>
<or>
<restlet:uri-template-filter pattern="/users" />
<restlet:uri-template-filter pattern="/users/{userId}" />
....
</or>
</filtering-router>
Filters can also work at the HTTP method level. This is handy if you wish to route POST/PUT requests to one place and GET requests to another (i.e. a cache).
<filtering-router>
<outbound-endpoint address="vm://userQueue"/>
<restlet:uri-template-filter pattern="/users" verbs="POST PUT"/>
</filtering-router>
If you have multiple HTTP methods, they should be separated by spaces.
Setting the payload and headers from URI templates
The URI template filters have a special capability to update a message's payload or headers based on the parameters in the template.
For example, if you want to extract an order ID from a URI and set it as the orderId property on the Message, you could do this:
<restlet:uri-template-filter pattern="/order/{set-header.orderId}" />
If you have a URI of the form "/order/123" this will set the property "orderId" to a value of "123" on the message.
You can also update the message payload:
<restlet:uri-template-filter pattern="/order/{set-payload.orderId}" />
This is useful when handling GET requests where the data you care about is actually in the URI.
Embedding Restlets in Mule
Restlet gives you the ability to build RESTful services via the Restlet and Resource APIs. This portion of the guide will lead you through a simple example. The Restlet documentation provides much more in depth instruction on how to build services and the APIs available.
Creating Resources
The first step in building a Restlet application is to design your "Resource". A Resource is a class which can be bound to URI. It contains methods which allow you to act on GET, POST, PUT, DELETE requests and represent the resource in different ways.
We're going to design a HelloWorldResource which serves out a hello world message in response to GET requests. This example is a slightly modified version from the Restlet user guide which is tweaked to show how to integrate it with Mule.
import org.restlet.Context;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.restlet.resource.StringRepresentation;
import org.restlet.resource.Variant;
public class HelloWorldResource extends Resource {
@SuppressWarnings("unchecked")
public HelloWorldResource(Context context, Request request, Response response) {
super(context, request, response);
getVariants().add(new Variant(MediaType.TEXT_PLAIN));
}
@Override
public Representation getRepresentation(Variant variant) {
return new StringRepresentation("Hello World", MediaType.TEXT_PLAIN);
}
}
This is our HelloWorld Resource and in it we are doing the following:
- Extending the Restlet Resource class which provides the basic resource functionality for our RESTful service
- Overriding the constructor and pass the context, request, and response to the super class.
- Adding a "text/plain" variant in the constructor. This tells Restlet that our Resource can serve text/plain resources. Your application may wish to service different or additional media types such as JSON or XML.
- Overriding the getRepresentation method. Here is where the logic to service different representations is located. In this case, we're serving a text/plain resource, so we create a StringRepresentation with the "Hello World" message.
Creating an Application
Since your application will most likely consist of a number of Resources, you'll want to encapsulate them. Restlet allows you to do this through the Application class. Inside the Application you can use a Restlet Router to direct requests to different Resources.
import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.Router;
import org.restlet.data.Request;
import org.restlet.data.Response;
public class HelloWorldApplication extends Application {
@Override
public Restlet createRoot() {
Router router = new Router(getContext());
router.attachDefault(HelloWorldResource.class);
return router;
}
}
Stepping through this code, we:
- Extend Application, which implements the Restlet interface. This is the class Mule is going to send messages to.
- Create a Restlet Router. The Router can send requests to various Resources based on the URI being requested. For our simple example, we're attaching the HelloWorldResource as the default resource. Since we have no other resources which have been attached to the router, it will always invoked.
Configuring Mule
The final step in creating your Restlet application is to embed it in Mule. To do this, we just create a service definition with a Restlet component in it:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.mulesource.org/schema/mule/core/2.0"
xmlns:restlet="http://www.mulesource.org/schema/mule/restlet/2.0"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.mulesource.org/schema/mule/core/2.0 http://www.mulesource.org/schema/mule/core/2.0/mule.xsd
http://www.mulesource.org/schema/mule/restlet/2.0 http://www.mulesource.org/schema/mule/restlet/2.0/mule-restlet.xsd">
<model name="helloModel">
<service name="helloService">
<inbound>
<inbound-endpoint address="http://localhost:9002" remoteSync="true" />
</inbound>
<restlet:component restlet-ref="helloWorld"/>
</service>
</model>
<spring:bean id="helloWorld" class="org.mule.transport.restlet.hello.HelloWorldApplication"/>
</mule>
Our <restlet:component> element references a Spring bean in our Mule application. This spring bean is the HelloWorldApplication that we created above.
You now have a Restlet application deployed in Mule. To see the hello world message browse to http://localhost:9002.
Using the Restlet Client with Mule
Restlet includes a Client API which makes it easy to consume HTTP based services. Where as the MuleClient API is very message oriented, the Restlet Client API is Resource oriented and can make consuming HTTP services over Mule much easier than it would have been other wise.
Using the client is a threestep process. First, you must create a Restlet Engine which knows about Mule.
import com.noelios.restlet.Engine;
import org.mule.transport.restlet.client.MuleClientHelper;
Engine engine = new Engine(false);
engine.getRegisteredClients().add(new MuleClientHelper());
Engine.setInstance(engine);
Next create the client:
Client client = new Client(Protocol.HTTP);
And lastly, use the client!
Response response = client.get("http:);
response = client.post("http:, new StringRepresentation("hello"));