Apache Camel: Introduction & Core Concepts
Apache Camel is an open-source integration framework that implements Enterprise Integration Patterns (EIPs). It provides a routing and mediation engine that lets you define routing rules in Java DSL, XML, or annotations, connecting hundreds of components like files, HTTP, databases, message queues, and cloud services.
Contents
Core Concepts
Camel builds integration logic from a small set of composable abstractions. Understanding these six building blocks is the foundation for everything else.
| Concept | What it is |
|---|---|
CamelContext | The runtime container: holds routes, components, configurations, and the type converter registry. There is typically one per application. |
Route | A processing pipeline defined as a sequence of steps from a source endpoint through processors to one or more destination endpoints. |
Endpoint | A channel to a system or resource, described by a URI such as file:data/inboxkafka:orders?brokers=localhost:9092 |
Component | A factory for endpoints. Over 300 components are available: file, HTTP, Kafka, JPA, AWS S3, and more. |
Exchange | The message container that travels through a route. Holds an in-message, an optional out-message, headers, and properties. |
Processor | A single processing step that receives an Exchange |
Your First Route
Add the Camel BOM and a starter dependency, then define a route using RouteBuilder
<!-- Camel BOM — manages all camel-* versions -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bom</artifactId>
<version>4.6.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Core Camel (standalone, no Spring) -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
public class HelloCamel {
public static void main(String[] args) throws Exception {
DefaultCamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
@Override
public void configure() {
from("timer:tick?period=1000") // fire every 1 second
.log("Hello Camel!"); // log to console
}
});
context.start();
Thread.sleep(5000); // let it run for 5 seconds
context.stop();
}
}
timer:tick?period=1000timertickperiod=1000component:name?optionsEnterprise Integration Patterns
Camel ships implementations of the classic EIP patterns from the Hohpe & Woolf book. Here are four of the most commonly used:
| Pattern | DSL keyword | What it does |
|---|---|---|
| Content-Based Router | .choice().when().otherwise() | Routes a message to one of several destinations based on message content or headers. |
| Message Filter | .filter() | Passes the message on only if a predicate evaluates to true; drops it silently otherwise. |
| Splitter | .split() | Splits a single message (e.g. a JSON array) into multiple individual messages for processing. |
| Aggregator | .aggregate() | Collects multiple related messages and combines them into a single message using a strategy. |
// Content-Based Router example
from("direct:orders")
.choice()
.when(header("type").isEqualTo("VIP"))
.to("direct:vipOrders")
.when(header("type").isEqualTo("STANDARD"))
.to("direct:standardOrders")
.otherwise()
.to("direct:unknownOrders")
.end();
// Splitter example — splits a comma-separated body into individual messages
from("direct:batch")
.split(body().tokenize(","))
.log("Processing item: ${body}")
.end();
DSL Styles
Camel supports three equivalent ways to define routes. All three examples below define the same route: poll a file every 5 seconds and log its name.
Java DSL (RouteBuilder)
import org.apache.camel.builder.RouteBuilder;
public class MyRoute extends RouteBuilder {
@Override
public void configure() {
from("file:data/inbox?delay=5000")
.log("Processing file: ${header.CamelFileName}");
}
}
YAML DSL (camel-yaml-dsl: routes.yaml)
- route:
from:
uri: "file:data/inbox"
parameters:
delay: 5000
steps:
- log:
message: "Processing file: ${header.CamelFileName}"
XML DSL (camelContext in Spring XML or standalone)
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:data/inbox?delay=5000"/>
<log message="Processing file: ${header.CamelFileName}"/>
</route>
</camelContext>
Key Components Overview
Camel has over 300 components. These are the ones you will encounter most often:
| Component | Protocol / Technology | Example URI |
|---|---|---|
file | Local filesystem polling & writing | file:data/inbox?delete=true |
httphttps | HTTP client calls | https://api.example.com/orders |
timer | Periodic trigger (no external system) | timer:tick?period=5000 |
kafka | Apache Kafka produce & consume | kafka:orders?brokers=localhost:9092 |
direct | In-memory synchronous call between routes | direct:processOrder |
seda | In-memory async queue between routes | seda:asyncWork?concurrentConsumers=5 |
jpa | JPA entity polling & persistence | jpa:com.example.Order?delay=5000 |
rest | REST DSL: expose REST endpoints | rest("/api").get("/hello") |
The Exchange
The ExchangeProcessorexchange
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
public class ExchangeRoute extends RouteBuilder {
@Override
public void configure() {
from("timer:tick?period=2000")
.setBody(constant("Hello from Camel"))
.setHeader("myHeader", constant("customValue"))
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
// Read body
String body = exchange.getMessage().getBody(String.class);
// Read a header
String header = exchange.getMessage().getHeader("myHeader", String.class);
// Read an exchange property (set earlier in the route)
Object prop = exchange.getProperty("someProperty");
System.out.println("body=" + body + " header=" + header);
// Modify the body
exchange.getMessage().setBody(body.toUpperCase());
}
})
.log("Result: ${body}");
}
}
exchange.getMessage()exchange.getIn()setProperty