In this article we will discuss how to produce and consume REST services using Apache Camel. Firstly we will show an example of REST Producer, then we will lean how to expose REST Endpoints in Camel.
Coding a Camel REST Producer
In our first example, our Camel Route calls a REST Endpoint therefore it works as a REST Client.
If you need an introduction on Camel applications on Spring Boot we recommend checking this article: Camel with Spring Boot example
Therefore, assuming that your application runs on Spring Boot, the required list of dependencies is minimal: we will add Camel and Spring Boot Bill of Materials (BOM). Then, we will add the dependencies.
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot-version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-bom</artifactId> <version>${camel-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Next, add the dependencies:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-http-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-jackson-starter</artifactId> </dependency>
Please note that you need to include the camel-jackson-starter only if your Route performs marhshalling/unmarshalling, as in our example.
Next, let’s code the Camel Route which contains the REST Producer:
@Component public class RestRoute extends RouteBuilder { JacksonDataFormat jsonDataFormat = new JacksonDataFormat(Timer.class); @Override public void configure() throws Exception { restConfiguration().host("localhost").port(8080); from("timer:timer1?period={{timer.period}}").setHeader("id", simple("${random(6,9)}")) .to("rest:get:random/{id}").log("${body}"); from("timer://timer2?period={{timer.period}}").setBody().simple("Current time is ${header.firedTime}") .process(new TimerProcessor()).marshal(jsonDataFormat).to("rest:post:time").log("${body}"); } }
- The first Route loops over a Timer to execute a REST GET on the endpoint “/random/{id}”
- The second Route also loops over a Timer to perform a REST POST to the endpoint “/time” transforming a simple text into the Timer object.
The following TimerProcessor class takes care to transform the incoming String into the Timer class:
public class TimerProcessor implements Processor { public void process(Exchange exchange) throws Exception { String id = exchange.getIn().getBody(String.class); Timer t = new Timer(id); exchange.getIn().setBody(t); } }
The Jackson library automatically marshals the Timer class into JSON. The resulting output is sent to the “/time” endpoint.
In order to consume the REST Endpoint, we will add the following Spring Boot RESTController:
@RestController public class MyController { @GetMapping(value = "/random/{id}") public String getRandomString(@PathVariable("id") Integer id) { return "HTTP GET Got " + randomString(id); } @PostMapping("/time") public String getTime(@RequestBody Timer data) { return "HTTP POST Got " + data.getData(); } String randomString(int len) { String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; SecureRandom rnd = new SecureRandom(); StringBuilder sb = new StringBuilder(len); for (int i = 0; i < len; i++) sb.append(AB.charAt(rnd.nextInt(AB.length()))); return sb.toString(); } }
As you can see, the REST Controller does not do anything fancy: just returning a random String or printing the Timer object.
A Spring Boot Application Class completes our example:
@SpringBootApplication public class RestApplication { public static void main(String[] args) { SpringApplication.run(RestApplication.class, args); } }
Running the application
Start the Spring Boot application as usual with:
mvn install spring-boot:run
You will see that both Timers will start sending GET and POST requests to our Controller:

The source code for the Camel producer is available here: https://github.com/fmarchioni/masterspringboot/tree/master/camel/rest-producer
Producing REST from an Public Endpoint
The above example assumes that you have a REST Service available on the same machine. On the other hand, if you want to have a quicker set up of your REST Component, you could simply use any of the available REST Public Endpoints.
For example, the jsonplaceholder Domain offers some public REST Endpoints for testing purpose. Here is how to fetch the ToDoList Endpoint, which requires a Java Bean “Todo” that we will unmarshal to:
@Component public class RestRoute extends RouteBuilder { @Override public void configure() throws Exception { restConfiguration() .component("http") .host("https://jsonplaceholder.typicode.com"); from("timer:trigger?repeatCount=1") .to("rest:get:todos/1") .unmarshal().json(JsonLibrary.Jackson, Todo.class) .log("Fetched data: ${body}"); } }
Coding a Camel REST Consumer
In the second example, we will activate a set of REST Endpoints in Camel. Firstly, to activate the REST Endpoint you have to choose one possible implementation:
- servlet
- spark-rest
- netty-http
- jetty
Since Spring Boot already ships with a Web server, we will choose the basic Servlet implementation.
Here is our RouteBuilder:
@Component public class RestRoute extends RouteBuilder { @Override public void configure() throws Exception { restConfiguration().component("servlet").bindingMode(RestBindingMode.auto); rest().path("/rest").consumes("application/json").produces("application/json") .get("{name}").to("bean:serviceBean?method=hello(${headers.name})") .post().type(User.class).outType(User.class).to("bean:serviceBean?method=response"); } }
Here is the list of available endpoints:
- GET /rest : This endpoint has a Path Parameter “name” that serves as input parameter for the ServiceBean
- POST /rest : This endpoint returns an Object Type User through the Bean Service Bean
Here is the definition of the ServiceBean which basically receives as input an User (thanks to the outType construct):
@Component public class ServiceBean { public User response(User user) { user.setName(user.getName().toUpperCase()); return user; } public String hello(String name) { return "Hello "+name; } }
Building the REST Consumer
To build our application, it is required to add the Spring Boot and Camel dependencies and the starters needed to set up the REST Endpoint. In particular, as we use the Camel Servlet to expose REST services we will need also the camel-servlet-starter:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot-version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-bom</artifactId> <version>${camel-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-servlet-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-jackson-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-http-starter</artifactId> </dependency>
Testing the REST Consumer
Firstly, start the application as follows:
mvn install spring-boot:run
You will see from the Console that the Rest endpoints have been activated:

Let’s test the HTTP GET Route:
curl http://localhost:8080/camel/rest/John "Hello John"
Let’s test also the POST endpoint:
curl --request POST --data "{ \"name\": \"John\" }" --header "Content-Type: application/json" http://localhost:8080/camel/rest {"name":"JOHN"}
Changing the Web Context Path
You probably have noticed that our application uses the “camel” Web context to access the Endpoints. That is the default Web context where endpoints are registered. You can change in application.properties through this property:
camel.component.servlet.mapping.context-path=/services/*
Source code for the second example: https://github.com/fmarchioni/masterspringboot/tree/master/camel/camel-rest
Conclusion
In conclusion, the Camel REST Component and REST DSL provide a powerful and flexible solution for building RESTful web services with Apache Camel. With the REST DSL, developers can define RESTful endpoints and specify the HTTP methods and URI patterns in a concise and intuitive way. The REST Component offers a high-level abstraction for handling RESTful requests and responses, allowing developers to focus on business logic rather than low-level HTTP handling.