Apache Camel: REST DSL
The Camel REST DSL lets you declare RESTful HTTP endpoints in a clean, readable style: directly inside your RouteBuilder. Camel translates these declarations into routes backed by any HTTP component (Netty, Undertow, Servlet, or camel-rest-starter). You get full EIP power inside each endpoint handler while keeping the API contract readable and separate.
Contents
Setup & Dependencies
Add camel-spring-boot-startercamel-servlet-starter
<!-- Core Camel Spring Boot -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
<!-- REST transport via Spring MVC / embedded Tomcat -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
</dependency>
<!-- JSON data-format for binding -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId>
</dependency>
# application.properties
camel.servlet.mapping.context-path=/api/*
camel.springboot.main-run-controller=true
Defining REST Endpoints
Use rest()RouteBuilderrestConfiguration()
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
@Component
public class OrderRestRoute extends RouteBuilder {
@Override
public void configure() {
restConfiguration()
.component("servlet")
.bindingMode(RestBindingMode.json) // auto marshal/unmarshal JSON
.dataFormatProperty("prettyPrint", "true")
.port(8080)
.contextPath("/api");
rest("/orders")
.description("Order service API")
.get("/")
.description("List all orders")
.to("direct:getAllOrders")
.get("/{id}")
.description("Get order by ID")
.to("direct:getOrder")
.post("/")
.description("Create a new order")
.type(Order.class)
.to("direct:createOrder")
.delete("/{id}")
.description("Delete an order")
.to("direct:deleteOrder");
}
}
to("direct:...")from("direct:...")Path & Query Parameters
Path parameters are automatically extracted from the URI and placed in message headers. Use header("id")
from("direct:getOrder")
.log("Looking up order: ${header.id}")
.process(exchange -> {
String id = exchange.getIn().getHeader("id", String.class);
Order order = orderService.findById(id);
exchange.getIn().setBody(order);
});
// Query parameters are also in headers
// GET /api/orders?status=PENDING
rest("/orders")
.get("/search")
.param().name("status").type(RestParamType.query).required(false).endParam()
.to("direct:searchOrders");
from("direct:searchOrders")
.process(exchange -> {
String status = exchange.getIn().getHeader("status", String.class);
exchange.getIn().setBody(orderService.findByStatus(status));
});
JSON Binding with Jackson
With bindingMode(RestBindingMode.json)type()
public class Order {
private String id;
private String product;
private int quantity;
private String status;
// getters and setters
}
// In RouteBuilder:
rest("/orders")
.post("/")
.type(Order.class) // deserialize request JSON → Order
.outType(Order.class) // serialize response Order → JSON
.to("direct:createOrder");
from("direct:createOrder")
.process(exchange -> {
Order order = exchange.getIn().getBody(Order.class);
order.setId(UUID.randomUUID().toString());
order.setStatus("CREATED");
Order saved = orderService.save(order);
exchange.getIn().setBody(saved);
});
type()outType()Connecting REST to Routes
Processing routes handle the business logic. Separate them from the REST declarations so each route has a single responsibility.
@Component
public class OrderProcessingRoute extends RouteBuilder {
@Override
public void configure() {
from("direct:getAllOrders")
.bean(OrderService.class, "findAll")
.log("Returning ${body.size} orders");
from("direct:createOrder")
.log("Creating order: ${body}")
.bean(OrderService.class, "save")
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(201));
from("direct:deleteOrder")
.process(exchange -> {
String id = exchange.getIn().getHeader("id", String.class);
orderService.delete(id);
exchange.getIn().setBody(null);
})
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(204));
}
}
OpenAPI / Swagger Integration
Add camel-openapi-java/api/api-doc/webjars/swagger-ui/index.html
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-openapi-java-starter</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>5.11.0</version>
</dependency>
restConfiguration()
.component("servlet")
.bindingMode(RestBindingMode.json)
.apiContextPath("/api-doc")
.apiContextRouteId("api-doc-route")
.apiProperty("api.title", "Order Service API")
.apiProperty("api.version", "1.0")
.apiProperty("cors", "true");
type()outType()param()REST Configuration Options
Key restConfiguration()
restConfiguration()
.component("servlet") // servlet | netty-http | undertow | jetty
.scheme("https") // http or https
.host("0.0.0.0")
.port(8443)
.contextPath("/api")
.bindingMode(RestBindingMode.json)
// Enable CORS for browser clients
.enableCORS(true)
.corsHeaderProperty("Access-Control-Allow-Origin", "*")
// JSON formatting
.dataFormatProperty("prettyPrint", "true")
// OpenAPI spec endpoint
.apiContextPath("/api-doc")
.apiProperty("api.title", "My API")
.apiProperty("api.version", "1.0");
enableCORS(true)*corsHeaderProperty("Access-Control-Allow-Origin", "https://yourdomain.com")