Apache Camel: Kafka Component
The Camel Kafka component lets you produce to and consume from Kafka topics using the familiar Camel route DSL, integrating Kafka into any Camel integration route without writing Kafka producer/consumer code directly.
Contents
Dependency
Add the camel-kafka-startercamel-kafka
<!-- Spring Boot -->
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-kafka-starter</artifactId>
</dependency>
<!-- Standalone Camel (non-Spring Boot) -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-kafka</artifactId>
</dependency>
Consuming from Kafka
Use from("kafka:<topic>?...")
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
@Component
public class KafkaConsumerRoute extends RouteBuilder {
@Override
public void configure() {
from("kafka:orders"
+ "?brokers=localhost:9092"
+ "&groupId=camel-order-group"
+ "&autoOffsetReset=earliest"
+ "&maxPollRecords=50")
.routeId("kafka-consumer")
.log("Received from Kafka: ${body}")
.to("direct:processOrder");
from("direct:processOrder")
.log("Processing order: ${body}");
}
}
Producing to Kafka
Use to("kafka:<topic>?...")KafkaConstants.KEY
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.kafka.KafkaConstants;
import org.springframework.stereotype.Component;
@Component
public class KafkaProducerRoute extends RouteBuilder {
@Override
public void configure() {
// Simple produce — body becomes the Kafka record value
from("timer:trigger?period=5000")
.setBody(constant("New order event"))
.to("kafka:processed-orders?brokers=localhost:9092");
// Produce with a message key
from("direct:sendWithKey")
.setHeader(KafkaConstants.KEY, header("orderId")) // use a route header as the Kafka key
.to("kafka:processed-orders?brokers=localhost:9092");
// Produce to a specific partition
from("direct:sendToPartition")
.setHeader(KafkaConstants.PARTITION_KEY, constant(0))
.to("kafka:processed-orders?brokers=localhost:9092");
}
}
Kafka Headers in Camel
When consuming from Kafka, Camel populates exchange headers with record metadata. When producing, you can set these headers to control how the record is written.
| Header Constant | Direction | Description |
|---|---|---|
KafkaConstants.TOPIC | Consume | The topic the message was received from. |
KafkaConstants.KEY | Both | The Kafka record key (as a String by default). |
KafkaConstants.PARTITION_KEY | Both | The partition number. Set when producing to target a specific partition. |
KafkaConstants.OFFSET | Consume | The offset of the consumed record. |
KafkaConstants.TIMESTAMP | Consume | The record timestamp in milliseconds since epoch. |
KafkaConstants.HEADERS | Both | Kafka record headers (Map of key → byte[]). |
from("kafka:orders?brokers=localhost:9092&groupId=camel-group")
.process(exchange -> {
String topic = exchange.getMessage().getHeader(KafkaConstants.TOPIC, String.class);
String key = exchange.getMessage().getHeader(KafkaConstants.KEY, String.class);
Integer partition = exchange.getMessage().getHeader(KafkaConstants.PARTITION_KEY, Integer.class);
Long offset = exchange.getMessage().getHeader(KafkaConstants.OFFSET, Long.class);
System.out.printf("topic=%s key=%s partition=%d offset=%d%n",
topic, key, partition, offset);
});
Key Configuration Options
Kafka component URI options map directly to Kafka consumer and producer config properties:
| URI Option | Default | Description |
|---|---|---|
brokers | - | Comma-separated list of bootstrap brokers (required). |
groupId | - | Consumer group ID (required for consumers). |
autoOffsetReset | latest | Where to start reading when no committed offset exists (earliestlatest |
maxPollRecords | 500 | Maximum records returned in a single poll call. |
seekTo | - | Seek to beginningend |
autoCommitEnable | true | Enable/disable auto offset commit. Set to false |
concurrentConsumers | 1 | Number of consumer threads (up to partition count). |
keyDeserializer | StringDeserializer | Deserializer class for message keys. |
valueDeserializer | StringDeserializer | Deserializer class for message values. |
Spring Boot Configuration
Configure the Kafka component globally in application.propertiescamel.component.kafka.*
# Component-level defaults — apply to all Kafka endpoints
camel.component.kafka.brokers=localhost:9092
camel.component.kafka.group-id=camel-app-group
camel.component.kafka.auto-offset-reset=earliest
camel.component.kafka.max-poll-records=100
camel.component.kafka.concurrent-consumers=3
# Security (optional)
camel.component.kafka.security-protocol=SASL_SSL
camel.component.kafka.sasl-mechanism=PLAIN
camel.component.kafka.sasl-jaas-config=org.apache.kafka.common.security.plain.PlainLoginModule required username="user" password="secret";
// With component-level defaults set, the route URI becomes much shorter
@Component
public class OrderRoute extends RouteBuilder {
@Override
public void configure() {
// brokers and groupId come from application.properties
from("kafka:orders")
.log("Received: ${body}")
.to("kafka:processed-orders");
}
}
application.propertiescamel.component.kafka.*