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

Compare with Current View Page History

« Previous Version 6 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.

Rest DSL with XML

The REST DSL supports the XML DSL also using either Spring or Blueprint. The example above can be define in XML as shown below:

  <camelContext xmlns="http://camel.apache.org/schema/spring">
    <rest uri="/say/hello">
      <get>
        <to uri="direct:hello"/>
      </get>
    </rest>
    <rest uri="/say/bye">
      <get consumes="application/json">
        <to uri="direct:bye"/>
      </get>
      <post>
        <to uri="mock:update"/>
      </post>
    </rest>
    <route>
      <from uri="direct:hello"/>
      <transform>
        <constant>Hello World</constant>
      </transform>
    </route>
    <route>
      <from uri="direct:bye"/>
      <transform>
        <constant>Bye World</constant>
      </transform>
    </route>
  </camelContext>

 

Using path prefixes

The REST DSL allows to define path prefixes to make the DSL a bit more DRY. For example to define a customer path, we can set the prefix in rest("/customer") and then provide the past postfix in the verbs, as shown below:

  rest("/customers/")
      .get("/{id}").to("direct:customerDetail")
      .get("/{id}/orders").to("direct:customerOrders")
      .post("/neworder").to("direct:customerNewOrder");

 

And using XML DSL it becomes:

    <rest uri="/customers/">
      <get uri="/{id}">
        <to uri="direct:customerDetail"/>
      </get>
      <get uri="/{id}/orders">
        <to uri="direct:customerOrders"/>
      </get>
      <post uri="/neworder">
        <to uri="direct:customerNewOrder"/>
      </post>
    </rest>

The REST DSL will take care of duplicate path separators when using path prefixes. In the example above the rest path prefix ends with a slash ( / ) and the verb starts with a slash ( / ). But Apache Camel will take care of this and remove the duplicated slash.

Embedding Camel routes

Each of the rest service becomes a Camel route, so in the first example we have 2 x get and 1 x post REST service, which each become a Camel route. And we have 2 regular Camel routes, meaning we have 3 + 2 = 5 routes in total. 

There are two route modes with the Rest DSL

  • mini using a singular to
  • embedding a Camel route using route 

The first example is using the former with a singular to. And that is why we end up with 3 + 2 = 5 total routes.

The same example could use embedded Camel routes, which is shown below:

    protected RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                rest("/say/hello")
                    .get().route().transform().constant("Hello World");
                rest("/say/bye")
                    .get().consumes("application/json").route().transform().constant("Bye World").endRest()
                    .post().to("mock:update");
        };
    }

In the example above, we are embedding routes directly in the rest service using .route(). Notice we need to use .endRest() to tell Camel where the route ends, so we can go back to the Rest DSL and continue defining REST services.

Configuring route options

In the embedded route you can configure the route settings such as routeId, autoStartup and various other options you can set on routes today.

.get().route().routeId("myRestRoute").autoStartup(false).transform().constant("Hello World");

 Managing Rest services

Each of the rest service becomes a Camel route, so in the first example we have 2 x get and 1 x post REST service, which each become a Camel route. This makes it the same from Camel to manage and run these services - as they are just Camel routes. This means any tooling and API today that deals with Camel routes, also work with the REST services.

This means you can use JMX to stop/start routes, and also get the JMX metrics about the routes, such as number of message processed, and their performance statistics.

Example - camel-example-spark-rest-tomcat

We provide an example that uses the REST DSL with the Spark Rest component that can be deployed in web containers such as Apache Tomcat. This example 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. 

Configuring Rest DSL

The Rest DSL allows to configure the following options using a builder style

 

OptionDefaultDescription
component The Camel Rest component to use for the REST transport, such as restlet, spark-rest. If no component has been explicit configured, then Camel will lookup if there is a Camel component that integrates with the Rest DSL, or if a org.apache.camel.spi.RestConsumerFactory is registered in the registry. If either one is found, then that is being used.
schemehttpThe scheme to use for exposing the REST service. Usually http or https is supported
hostname0.0.0.0The hostname to use for exposing the REST service.
port The port number to use for exposing the REST service.
property Allows to configure as many additional properties. This is used to configure component specific options such as for Restlet / Spark-Rest etc.

 

For example to configure to use the spark-rest component on port 9091, then we can do as follows

restConfiguration().component("spark-rest").port(9091).property("foo", "123");


And with XML DSL

<restConfiguration component="spark-rest" port="9091"> <restProperty key="foo" value="123"/> </restConfiguration>


Integration a Camel component with Rest DSL

Any Apache Camel component can integrate with the Rest DSL if they can be used as a REST service (eg as a REST consumer in Camel lingo). To integrate with the Rest DSL, then the component should implement the org.apache.camel.spi.RestConsumerFactory. The Rest DSL will then invoke the createConsumer method when it setup the Camel routes from the defined DSL. The component should then implement logic to create a Camel consumer that exposes the REST services based on the given parameters, such as path, verb, and other options. For example see the source code for camel-restlet, camel-spark-rest.

 

See Also

DSL

Rest

Restlet

Spark-rest

  • No labels