Skip to content
Kafka Is FunProgress

Advanced Patterns · Advanced

Kafka Streams with Spring Boot

Spring Boot autoconfigures Kafka Streams when spring.kafka.streams properties are set. Use @EnableKafkaStreams and inject StreamsBuilder.

OrderStreamProcessor.javajava
@Configuration
@EnableKafkaStreams
@Slf4j
public class OrderStreamProcessor {

    @Autowired
    public KStream<String, OrderEvent> buildOrderPipeline(StreamsBuilder streamsBuilder) {

        // Deserialize
        var orderSerde = new JsonSerde<>(OrderEvent.class);

        KStream<String, OrderEvent> orders = streamsBuilder
            .stream("orders.order.created",
                Consumed.with(Serdes.String(), orderSerde));

        // Filter + transform + route
        orders
            .filter((key, event) -> event.getAmount() > 1000)
            .mapValues(event -> EnrichedOrder.from(event, lookupService.getCustomer(event.getCustomerId())))
            .to("orders.high-value", Produced.with(Serdes.String(), new JsonSerde<>(EnrichedOrder.class)));

        // Aggregate: count orders per customer (tumbling window, 1 hour)
        orders
            .groupByKey()
            .windowedBy(TimeWindows.ofSizeWithNoGrace(Duration.ofHours(1)))
            .count()
            .toStream()
            .map((windowedKey, count) ->
                KeyValue.pair(windowedKey.key(), new OrderCount(windowedKey.key(), count)))
            .to("analytics.order-counts", Produced.with(Serdes.String(), new JsonSerde<>(OrderCount.class)));

        return orders;
    }
}
application.yml (Streams config)yaml
spring:
  kafka:
    streams:
      application-id: order-stream-processor
      bootstrap-servers: localhost:9092
      default-key-serde: org.apache.kafka.common.serialization.Serdes$StringSerde
      properties:
        processing.guarantee: exactly_once_v2
        num.stream.threads: 4
        cache.max.bytes.buffering: 10485760  # 10MB state cache
        state.dir: /tmp/kafka-streams