You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

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 RestletSpark-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 templateVerbConsumes
/say/hellogetall
/say/byegetapplication/json
/say/byepostall

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 transformationAnd 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.

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        errorHandler(deadLetterChannel("mock:error"));


        from("direct:a").to("direct:b");
    }
};


As you can see from the above Camel uses URIs to wire endpoints together.

URI String formatting

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.

from("direct:start").toF("file://%s?fileName=%s", path, name);

fromF("file://%s?include=%s", path, pattern).toF("mock:%s", result);

Filters

You can combine simple routes with filters which can be arbitrary Predicate implementations.

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        errorHandler(deadLetterChannel("mock:error"));

        from("direct:a")
            .filter(header("foo").isEqualTo("bar"))
                .to("direct:b");
    }
};

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.

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        errorHandler(deadLetterChannel("mock:error"));

        from("direct:a")
            .choice()
                .when(header("foo").isEqualTo("bar"))
                    .to("direct:b")
                .when(header("foo").isEqualTo("cheese"))
                    .to("direct:c")
                .otherwise()
                    .to("direct:d");
    }
};

Using a custom processor

Here is an example of using a custom Processor

myProcessor = new Processor() {
    public void process(Exchange exchange) {
        log.debug("Called with exchange: " + exchange);
    }
};

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        errorHandler(deadLetterChannel("mock:error"));

        from("direct:a")
            .process(myProcessor);
    }
};

You can mix and match custom processors with filters and choices.

RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        errorHandler(deadLetterChannel("mock:error"));

        from("direct:a")
            .filter(header("foo").isEqualTo("bar"))
                .process(myProcessor);
    }
};

See Also

  • No labels