Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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>"); } }

Binding to POJOs using

The Rest DSL supports automatic binding json/xml contents to/from POJOs using Camels Data Format. By default the binding mode is off, meaning there is no automatic binding happening for incoming and outgoing messages.

You may want to use binding if you develop POJOs that maps to your REST services request and response types. This allows you as a developer to work with the POJOs in Java code.

The binding modes are:

Binding ModeDescription
offBinding is turned off. This is the default option.
autoBinding is enabled and Camel is relaxed and support json, xml or both if the needed data formats are included in the classpath. Notice that if for example camel-jaxb is not on the classpath, then XML binding is not enabled.
jsonBinding to/from json is enabled, and requires a json capabile data format on the classpath. By default Camel will use json-jackson as the data format.
xmlBinding to/from xml is enabled, and requires camel-jaxb on the classpath.
json_xmlBiding to/from json and xml is enabled and requires both data formats to be on the classpath.

 

To use binding you must include the necessary data formats on the classpath, such as camel-jaxb and/or camel-jackson. And then enable the binding mode. You can configure the binding mode globally on the rest configuration, and then override per rest service as well.

To enable binding you configure this in Java DSL as shown below

Code Block
restConfiguration().component("restlet").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);

And in XML DSL

Code Block
    <restConfiguration bindingMode="auto" component="restlet" port="8080"/>

 

When binding is enabled Camel will bind the incoming and outgoing messages automatic, accordingly to the content type of the message. If the message is json, then json binding happens; and so if the message is xml then xml binding happens. The binding happens for incoming and reply messages. The table below summaries what binding occurs for incoming and reply messages. 

Message BodyDirectionBinding ModeMessage Body
XMLIncoming

auto
xml
json_xml 

POJO
POJOOutgoingauto
xml
json_xml 
XML
JSONIncomingauto
json
json_xml 
POJO
POJOOutgoingauto
json
json_xml 
JSON

 

When using binding you must also configure what POJO type to map to. This is mandatory for incoming messages, and optional for outgoing. 

For example to map from xml/json to a pojo class UserPojo you do this in Java DSL as shown below:

Code Block
// configure to use restlet on localhost with the given port
// and enable auto binding mode
restConfiguration().component("restlet").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);

// use the rest DSL to define the rest services
rest("/users/")
    .post("new").type(UserPojo.class)
        .to("direct:newUser");

Notice we use type to define the incoming type. We can optionally define an outgoing type (which can be a good idea, to make it known from the DSL and also for tooling and JMX APIs to know both the incoming and outgoing types of the REST services.). To define the outgoing type, we use outType as shown below:

Code Block
// configure to use restlet on localhost with the given port
// and enable auto binding mode
restConfiguration().component("restlet").host("localhost").port(portNum).bindingMode(RestBindingMode.auto);

// use the rest DSL to define the rest services
rest("/users/")
    .post("new").type(UserPojo.class).outType(CountryPojo.class)
        .to("direct:newUser");


The UserPojo is just a plain pojo with getter/setter as shown:

Code Block
public class UserPojo {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

The UserPojo only supports json, as XML requires to use JAXB annotations, so we can add those annotations if we want to support XML also

Code Block
@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserPojo {
    @XmlAttribute
    private int id;
    @XmlAttribute
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

By having the JAXB annotations the POJO supports both json and xml bindings.

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.
bindingModeoffWhether binding is in use. See further above for more details.
componentProperty Allows to configure as many additional properties. This is used to configure component specific options such as for Restlet / Spark-Rest etc.
endpointProperty Allows to configure as many additional properties. This is used to configure endpoint specific options for  Restlet / Spark-Rest etc.
consumerProperty Allows to configure as many additional properties. This is used to configure consumer specific options for  Restlet / Spark-Rest etc.

...