Skip to content
Kafka Is FunProgress

Production Patterns · Intermediate

Consumer with Message Headers

Kafka message headers carry metadata: trace IDs, event type, schema version, retry count. Essential for distributed tracing and routing.

HeaderAwareConsumer.javajava
@Service
public class HeaderAwareConsumer {

    // Inject specific headers via @Header
    @KafkaListener(topics = "orders.order.created")
    public void onOrder(
        OrderEvent event,
        @Header(KafkaHeaders.RECEIVED_TOPIC) String topic,
        @Header(KafkaHeaders.RECEIVED_PARTITION) int partition,
        @Header(KafkaHeaders.OFFSET) long offset,
        @Header(value = "X-Trace-Id", required = false) String traceId,
        @Header(value = "X-Event-Version", required = false) String eventVersion
    ) {
        MDC.put("traceId", traceId != null ? traceId : "unknown");
        log.info("Processing order from {}-{} @ offset {}", topic, partition, offset);
        // process...
    }
}

// Producer: add headers
@Service
public class TracingOrderProducer {

    public void publish(Order order) {
        var record = new ProducerRecord<>("orders.order.created",
            null, System.currentTimeMillis(), order.getId(),
            new OrderCreatedEvent(order));

        record.headers()
            .add("X-Trace-Id", TraceContext.current().toBytes())
            .add("X-Event-Version", "2".getBytes())
            .add("X-Source-Service", "order-service".getBytes());

        kafkaTemplate.send(record);
    }
}