Rest DSL
Available as of Camel 2.14
Apache Camel offers a REST styled DSL which can be used with Java or XML. The intention is to allow end users to define REST services using a REST style with verbs such as get, post, delete etc.
How it works
The Rest DSL is a facade that builds Rest endpoints as consumers for Camel routes. The actual REST transport is leveraged by using Camel REST components such as Restlet, Spark-rest, and others that has native REST integration.
Rest DSL with Java
To use the Rest DSL in Java then just do as with regular Camel routes by extending the RouteBuilder
and define the routes in the configure
method.
A simple REST service can be define as follows, where we use rest() to define the services as shown below:
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
rest("/say/hello")
.get().to("direct:hello");
rest("/say/bye")
.get().consumes("application/json").to("direct:bye")
.post().to("mock:update");
from("direct:hello")
.transform().constant("Hello World");
from("direct:bye")
.transform().constant("Bye World");
}
};
}
This defines a REST service with the following url mappings:
Uri template |
Verb |
Consumes |
/say/hello |
get |
all |
/say/bye |
get |
application/json |
/say/bye |
post |
all |
Notice that in the REST service we route directly to a Camel endpoint using the to(). This is because the Rest DSL has a short-hand for routing directly to an endpoint using to(). An alternative is to embed a Camel route directly using route() - there is such an example further below.
The example below defines a single REST service which offers a GET operation that accepts 3 different types: plain text, json, and xml.
public class MySparkRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
// configure we want to use spark-rest as the component for the rest DSL
restConfiguration().component("spark-rest");
// use the rest DSL to define rest services, and use embedded routes
rest("/hello/{me}")
.get().consumes("text/plain")
.route()
.to("log:input")
.transform().simple("Hello ${header.me}").endRest()
.get().consumes("application/json")
.route()
.to("log:input")
.transform().simple("{ \"message\": \"Hello ${header.me}\" }").endRest()
.get().consumes("text/xml")
.route()
.to("log:input")
.transform().simple("<message>Hello ${header.me}</message>");
}
}
To define the REST services we use the rest
method, where we can setup the path, which is "/hello/{me}". Where me refers the a wildcard that is mapped to Camel message header with the same key. Notice how we can refer to this header in the embedded Camel routes where we do message transformation. And because we used embedded routes, we need to define this using .route(), and to denote the end of the route, we use .endRest() to go back to the Rest DSL, where we can then add the 2nd, and 3rd get service.
Routes
Camel supports the definition of routing rules using a Java DSL (domain specific language) which avoids the need for cumbersome XML using a RouteBuilder.
For example a simple route can be created as follows.
As you can see from the above Camel uses URIs to wire endpoints together.
Available as of Camel 2.0
If you have endpoint URIs that accept options and you want to be able to substitute the value, e.g. build the URI by concat the strings together, then you can use the java.lang.String.format
method. But in Camel 2.0 we have added two convenient methods in the Java DSL so you can do fromF
and toF
that uses String formatting to build the URI.
Filters
You can combine simple routes with filters which can be arbitrary Predicate implementations.
Choices
With a choice you provide a list of predicates and outcomes along with an optional default otherwise clause which is invoked if none of the conditions are met.
Using a custom processor
Here is an example of using a custom Processor
You can mix and match custom processors with filters and choices.
Interceptors
Here is an example of adding a few custom InterceptorProcessor objects to a processing pipeline:
When you start defining and interceptor stack with intercept(), you must follow up with the subsequent .target() so that the target of the interceptor stack is properly registered.
See Also