Skip to content

feature/kafka message contract#150

Merged
bascunansalvador merged 7 commits into
mainfrom
feature/kafka-message-contract
Jun 24, 2026
Merged

feature/kafka message contract#150
bascunansalvador merged 7 commits into
mainfrom
feature/kafka-message-contract

Conversation

@bascunansalvador

@bascunansalvador bascunansalvador commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

The previous spring-kafka client generation was too close to runtime wiring. Generated producers owned KafkaTemplate usage and send-result behavior, while generated consumers exposed Spring Kafka ConsumerRecord values directly. That made the generated code feel more like an application runtime implementation than a contract generated from AsyncAPI.

This was risky because spring-kafka applications are commonly configured in many different ways. Users may use spring-boot YAML, custom KafkaTemplate beans, custom listener containers, schema registry configuration, byte-based payloads, native Avro, native Protobuf, or other application-specific runtime setup. If the generator owns too much of that wiring, it becomes hard to use safely across different application architectures.

For the proposed solution, spring-kafka generation now produces contract-first interfaces for both Java and Kotlin.

Producer-oriented channels now generate producer interfaces with abstract send methods. These methods expose the payload, Kafka record key, and contract-defined headers as method parameters. The generated producer no longer owns KafkaTemplate, ProducerRecord, CompletableFuture, SendResult, topic lookup, or header serialization.

Consumer-oriented channels now generate consumer interfaces with abstract handling methods. These methods expose the payload, nullable Kafka record key, and contract-defined headers as method parameters. The generated consumer no longer exposes ConsumerRecord, no longer imports Spring Kafka listener record types, and no longer requires generated header DTOs in the method signature.

Headers are now represented directly in producer and consumer method signatures. Required headers are generated as required parameters, and optional headers are generated as nullable/defaulted parameters depending on the target language. Header descriptions from the AsyncAPI contract are also included in generated method documentation.

The generated interfaces use validation annotations where appropriate. Kotlin contracts use @Validated and @param:Valid for payload parameters. Java contracts use @Validated, @Valid, @NotNull, and @Nullable so the generated signatures describe the expected contract without taking ownership of runtime behavior.

The internal generator model was also cleaned up. The old “handler” terminology was replaced with consumer-oriented naming, so the implementation now reflects that we generate consumer contract interfaces rather than handler/listener runtime components.

The previous DLT/DLQ-oriented contract examples were removed from this direction. Dead-letter handling is runtime error-handling configuration, not a first-class business message contract that should be generated by default.

The README was updated to describe the new Spring Kafka contract-first behavior. It now makes clear that applications implement the generated interfaces and own runtime wiring, topic resolution, Kafka template configuration, listener configuration, serialization, deserialization, and schema registry integration.

Test coverage was updated for Java and Kotlin Spring Kafka generation. The tests now verify that generated producers and consumers expose payloads, keys, and headers directly, and that they do not contain KafkaTemplate, ProducerRecord, ConsumerRecord, CompletableFuture, SendResult, or @KafkaListener runtime wiring.

@bascunansalvador bascunansalvador merged commit c82d3e3 into main Jun 24, 2026
1 check passed
@bascunansalvador bascunansalvador deleted the feature/kafka-message-contract branch June 24, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document Spring Kafka generated API behavior

1 participant