Spring-Kafka
Application Configuration
Kafka Topic
YAML
Kafka Programming

Spring-Kafka How to pass the kafka topic from the application.yml

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Passing a Kafka topic name from application.yml is a standard Spring Boot pattern because topic names often change by environment. Instead of hard-coding "orders" or "payments" in Java code, you define the topic once in configuration and inject it wherever producers or listeners need it.

Defining the Topic in application.yml

The cleanest approach is to put application-specific values under your own prefix instead of forcing everything into Spring Kafka's built-in properties. That keeps transport settings separate from business topic names.

yaml
app:
  kafka:
    order-topic: orders.v1

Now the topic is externalized and can be overridden for local, staging, or production environments.

Using @Value for a Simple Case

If you only need one or two values, @Value is enough:

java
1package example.kafka;
2
3import org.springframework.beans.factory.annotation.Value;
4import org.springframework.kafka.core.KafkaTemplate;
5import org.springframework.stereotype.Service;
6
7@Service
8public class OrderPublisher {
9
10    private final KafkaTemplate<String, String> kafkaTemplate;
11    private final String topic;
12
13    public OrderPublisher(
14            KafkaTemplate<String, String> kafkaTemplate,
15            @Value("${app.kafka.order-topic}") String topic) {
16        this.kafkaTemplate = kafkaTemplate;
17        this.topic = topic;
18    }
19
20    public void publish(String payload) {
21        kafkaTemplate.send(topic, payload);
22    }
23}

This is easy to read and works well for small applications. The topic can now be changed without touching Java code.

Using @ConfigurationProperties for Multiple Topics

Once your project has several topics, @ConfigurationProperties scales better. It is type-safe, easier to test, and avoids repeating property keys all over the codebase.

java
1package example.kafka;
2
3import org.springframework.boot.context.properties.ConfigurationProperties;
4
5@ConfigurationProperties(prefix = "app.kafka")
6public class KafkaTopicProperties {
7
8    private String orderTopic;
9    private String auditTopic;
10
11    public String getOrderTopic() {
12        return orderTopic;
13    }
14
15    public void setOrderTopic(String orderTopic) {
16        this.orderTopic = orderTopic;
17    }
18
19    public String getAuditTopic() {
20        return auditTopic;
21    }
22
23    public void setAuditTopic(String auditTopic) {
24        this.auditTopic = auditTopic;
25    }
26}

Register the properties class:

java
1package example.kafka;
2
3import org.springframework.boot.context.properties.EnableConfigurationProperties;
4import org.springframework.context.annotation.Configuration;
5
6@Configuration
7@EnableConfigurationProperties(KafkaTopicProperties.class)
8public class KafkaTopicConfig {
9}

Then inject it:

java
1package example.kafka;
2
3import org.springframework.kafka.core.KafkaTemplate;
4import org.springframework.stereotype.Service;
5
6@Service
7public class AuditPublisher {
8
9    private final KafkaTemplate<String, String> kafkaTemplate;
10    private final KafkaTopicProperties properties;
11
12    public AuditPublisher(
13            KafkaTemplate<String, String> kafkaTemplate,
14            KafkaTopicProperties properties) {
15        this.kafkaTemplate = kafkaTemplate;
16        this.properties = properties;
17    }
18
19    public void publish(String payload) {
20        kafkaTemplate.send(properties.getAuditTopic(), payload);
21    }
22}

Passing the Topic into a Listener

Spring Kafka also lets you resolve property placeholders in annotations such as @KafkaListener. That means the listener topic can live in YAML too.

java
1package example.kafka;
2
3import org.springframework.kafka.annotation.KafkaListener;
4import org.springframework.stereotype.Component;
5
6@Component
7public class OrderListener {
8
9    @KafkaListener(topics = "${app.kafka.order-topic}", groupId = "orders-service")
10    public void onMessage(String payload) {
11        System.out.println("Received: " + payload);
12    }
13}

This is often the most convenient option for consumers because the mapping between configuration and listener is direct.

Why This Is Better Than Hard-Coding

Externalized topics make deployment safer. A developer can point the same code at a test topic locally and a production topic in a real cluster by changing configuration only. It also makes renaming topics less invasive because the value lives in one place rather than across multiple source files.

This approach also supports profile-specific files such as application-dev.yml and application-prod.yml, which is useful when clusters and topic names differ across environments.

Common Pitfalls

One common mistake is storing business topic names under unrelated built-in keys just because Spring Kafka already has a spring.kafka section. That can make the configuration harder to understand. Use your own prefix for application-level topic names.

Another issue is mismatched property names. For example, order-topic in YAML maps to orderTopic in a configuration properties class. If the naming does not line up, the injected value may stay null.

A third pitfall is hard-coding the producer topic but externalizing the listener topic. That creates drift over time. If a topic is meant to be configurable, keep it configurable everywhere.

Finally, remember that putting a topic name in YAML does not create the topic in Kafka. Topic existence, partitions, and retention settings are still operational concerns unless your platform auto-creates them.

Summary

  • Define Kafka topic names in application.yml so they can vary by environment.
  • Use @Value for one or two simple properties.
  • Use @ConfigurationProperties when you have several topics or want type-safe configuration.
  • '@KafkaListener(topics = "${...}") can read topic names directly from YAML.'
  • Externalized topic names improve maintainability and reduce hard-coded environment details.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.