Skip to content

refactor(api): normalize KPipe.avro/protobuf arg order to (topic, props, format)#201

Merged
eschizoid merged 1 commit into
mainfrom
refactor/kpipe-arg-order-normalize
Jun 20, 2026
Merged

refactor(api): normalize KPipe.avro/protobuf arg order to (topic, props, format)#201
eschizoid merged 1 commit into
mainfrom
refactor/kpipe-arg-order-normalize

Conversation

@eschizoid

Copy link
Copy Markdown
Owner

Summary

Normalize the static-mode KPipe.avro / KPipe.protobuf overloads (and the corresponding MultiBuilder per-format methods) so the format argument comes last, matching the established shape of KPipe.custom(topic, props, format) and KPipe.avro(topic, props, resolver). The §17 capability table already documents (topic, props, format) as the canonical shape — the static-mode Avro/Protobuf overloads were the outliers.

The asymmetry (before)

  • KPipe.avro(AvroFormat format, String topic, Properties kafkaProps) — format first
  • KPipe.protobuf(ProtobufFormat format, String topic, Properties kafkaProps) — format first
  • KPipe.custom(String topic, Properties kafkaProps, MessageFormat<T> format) — format last (canonical)
  • KPipe.avro(String topic, Properties kafkaProps, SchemaResolver resolver) — resolver last (consistent with custom)
  • KPipe.json/bytes(String topic, Properties kafkaProps) — no format arg

The fix

Hard-rename all six entry points (no @Deprecated overloads kept) and migrate every caller in the same PR, per the no-deprecation policy.

  • KPipe.avro(String topic, Properties kafkaProps, AvroFormat format)
  • KPipe.avro(Collection<String> topics, Properties kafkaProps, AvroFormat format)
  • KPipe.protobuf(String topic, Properties kafkaProps, ProtobufFormat format)
  • KPipe.protobuf(Collection<String> topics, Properties kafkaProps, ProtobufFormat format)
  • MultiBuilder.avro(String topic, AvroFormat format, Function<…> configurator)
  • MultiBuilder.protobuf(String topic, ProtobufFormat format, Function<…> configurator)

The SR-mode KPipe.avro(topic, props, SchemaResolver), KPipe.json/bytes, and KPipe.custom are unchanged — they already match the canonical shape.

Pre-verification (caller enumeration before migration)

$ grep -rn "KPipe.avro\b\|KPipe.protobuf\b" lib/ examples/ benchmarks/ --include="*.java"
lib/kpipe-api/src/test/java/io/github/eschizoid/kpipe/ToConsoleDispatchTest.java:44:    final var sink = (DefaultSink<?>) KPipe.avro(format, "t", props()).toConsole();
lib/kpipe-api/src/test/java/io/github/eschizoid/kpipe/ToConsoleDispatchTest.java:52:    final var sink = (DefaultSink<?>) KPipe.protobuf(format, "t", props()).toConsole();
lib/kpipe-api/src/main/java/io/github/eschizoid/kpipe/KPipe.java:111:        "KPipe.avro(new AvroFormat(schema), topic, props) to keep the console-sink path."
lib/kpipe-format-avro/src/main/java/io/github/eschizoid/kpipe/format/avro/AvroFormat.java:46:/// Schema-Registry mode replaces the manual `KPipe.avro(...).skipBytes(5).pipe(...)` pattern.
examples/schema-registry/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java:97:      final var handle = KPipe.avro(format, topic, consumerProps())
examples/schema-registry/src/main/java/io/github/eschizoid/kpipe/App.java:38:      final var handle = KPipe.avro(config.topic(), props, resolver)
examples/avro/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java:65:    try (final var handle = KPipe.avro(format, topic, consumerProps()).skipBytes(5).toCustom(capturingSink).start()) {
examples/avro/src/main/java/io/github/eschizoid/kpipe/App.java:32:    try (final var handle = KPipe.avro(format, config.topic(), props).skipBytes(5).toConsole().start()) {
examples/protobuf/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java:56:      final var handle = KPipe.protobuf(format, topic, consumerProps())
examples/protobuf/src/main/java/io/github/eschizoid/kpipe/App.java:27:    try (final var handle = KPipe.protobuf(format, config.topic(), props).toConsole().start()) {

$ grep -rn "\.avro(.*format.*topic\|\.protobuf(.*format.*topic" lib/ examples/ benchmarks/ --include="*.java"
examples/schema-registry/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java:97:      final var handle = KPipe.avro(format, topic, consumerProps())
examples/avro/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java:65:    try (final var handle = KPipe.avro(format, topic, consumerProps()).skipBytes(5).toCustom(capturingSink).start()) {
examples/avro/src/main/java/io/github/eschizoid/kpipe/App.java:32:    try (final var handle = KPipe.avro(format, config.topic(), props).skipBytes(5).toConsole().start()) {
examples/protobuf/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java:56:      final var handle = KPipe.protobuf(format, topic, consumerProps())
examples/protobuf/src/main/java/io/github/eschizoid/kpipe/App.java:27:    try (final var handle = KPipe.protobuf(format, config.topic(), props).toConsole().start()) {

The examples/schema-registry/.../App.java:38 hit is the SR-mode (topic, props, resolver) overload — already canonical, not migrated.

The Javadoc and code-comment mentions inside lib/kpipe-api/src/main/java/io/github/eschizoid/kpipe/KPipe.java and lib/kpipe-format-avro/src/main/java/io/github/eschizoid/kpipe/format/avro/AvroFormat.java referenced the old shape verbatim — those were updated in-place.

There are no KPipe.avro / KPipe.protobuf callers in benchmarks/.

Migrated callers

Library

  • lib/kpipe-api/src/main/java/io/github/eschizoid/kpipe/KPipe.java — overload signatures + Javadoc + the registryModeConsoleSinkUnsupported error message
  • lib/kpipe-api/src/main/java/io/github/eschizoid/kpipe/MultiBuilder.javaavro / protobuf route method signatures + class-level Javadoc example
  • lib/kpipe-format-avro/src/main/java/io/github/eschizoid/kpipe/format/avro/AvroFormat.java — Javadoc reference to the old KPipe.avro(...).skipBytes(5) pattern

Tests

  • lib/kpipe-api/src/test/java/io/github/eschizoid/kpipe/ToConsoleDispatchTest.javaavroToConsoleDispatchesToAvroConsoleSink + protobufToConsoleDispatchesToProtobufConsoleSink

Examples

  • examples/avro/src/main/java/io/github/eschizoid/kpipe/App.java
  • examples/avro/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java
  • examples/protobuf/src/main/java/io/github/eschizoid/kpipe/App.java
  • examples/protobuf/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java
  • examples/schema-registry/src/test/java/io/github/eschizoid/kpipe/AppIntegrationTest.java (the static-mode call site)
  • examples/demo/src/main/java/io/github/eschizoid/kpipe/demo/DemoApp.java (MultiBuilder.avro / .protobuf)

Docs

  • README.md — equivalence note for the SR-shorthand

No-deprecation policy

Per the project's no-deprecation policy: no @Deprecated overloads, no @deprecated Javadoc, no shim layer. The rename and all caller migrations land in this one PR so users always have a working reference and the surface stays clean. Same playbook as the prior withSequentialProcessing(boolean) removal.

Test plan

  • ./gradlew :lib:kpipe-api:test :examples:avro:compileJava :examples:protobuf:compileJava :benchmarks:compileJmhJava → green (BUILD SUCCESSFUL in 2m 17s)
  • ./gradlew :examples:demo:compileJava → green (DemoApp uses MultiBuilder.avro / .protobuf)
  • ./gradlew :examples:schema-registry:compileJava :examples:schema-registry:compileTestJava :examples:avro:compileTestJava :examples:protobuf:compileTestJava → green
  • Final caller grep shows zero (format, topic, …) call sites remaining.

…ps, format)

The static-mode KPipe.avro/protobuf overloads took (format, topic, props)
while KPipe.custom and the SR-mode KPipe.avro(topic, props, resolver) both
put the format/resolver last. The §17 capability table documents the
canonical shape as (topic, props, format) — the static-mode overloads were
the outliers.

Normalize all static-mode entry points to put the format last:
- KPipe.avro(String topic, Properties props, AvroFormat format)
- KPipe.avro(Collection<String> topics, Properties props, AvroFormat format)
- KPipe.protobuf(String topic, Properties props, ProtobufFormat format)
- KPipe.protobuf(Collection<String> topics, Properties props, ProtobufFormat format)
- MultiBuilder.avro(String topic, AvroFormat format, configurator)
- MultiBuilder.protobuf(String topic, ProtobufFormat format, configurator)

Hard-rename + migrate all callers in the same PR per the no-deprecation
policy. No @deprecated overloads kept for back-compat.
@eschizoid

Copy link
Copy Markdown
Owner Author

@copilot please review

@codecov

codecov Bot commented Jun 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.74%. Comparing base (4ccac98) to head (d630aa8).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main     #201      +/-   ##
============================================
- Coverage     77.82%   77.74%   -0.08%     
+ Complexity      732      722      -10     
============================================
  Files            68       66       -2     
  Lines          2800     2795       -5     
  Branches        346      348       +2     
============================================
- Hits           2179     2173       -6     
  Misses          462      462              
- Partials        159      160       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@eschizoid eschizoid merged commit cade7d6 into main Jun 20, 2026
3 of 4 checks passed
@eschizoid eschizoid deleted the refactor/kpipe-arg-order-normalize branch June 22, 2026 04:02
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.

1 participant