Skip to content

feat(pubsub): promote BulkPublishEventAlpha1 to stable BulkPublishEvent - #1

Merged
markjgardner merged 1 commit into
mainfrom
markjgardner-feat-pubsub-stable-bulk-publish
Sep 17, 2026
Merged

markjgardner merged 1 commit into
mainfrom
markjgardner-feat-pubsub-stable-bulk-publish

Conversation

@markjgardner

Copy link
Copy Markdown
Owner

Description

Dapr promoted the bulk publish API out of alpha in runtime 1.17, but the JS SDK still called the alpha1 variants on both transports. This moves client.pubsub.publishBulk(...) onto the stable API without dropping support for the runtimes people are actually on.

Approach: stable first, with a transparent fallback.

  • gRPC calls BulkPublishEvent and retries BulkPublishEventAlpha1 when the sidecar answers UNIMPLEMENTED.
  • HTTP calls v1.0/publish/bulk/{pubsubName}/{topic} and retries v1.0-alpha1 on a 404.
  • The vendored proto backports the stable BulkPublishEvent RPC and marks alpha1 deprecated, matching upstream dapr/dapr byte for byte. Affected stubs were regenerated.

The public surface does not change. publishBulk keeps the same name, parameters, and return type, so no consumer code needs updating. The downgrade is remembered per client, so a pre-1.17 sidecar costs at most one extra round trip rather than one per call.

Why a fallback rather than a hard switch. A hard switch is not actually available here. The stable RPC is absent from the pinned v1.16.0 proto, so it would require bumping the pin, and Dapr 1.17 split dapr.proto into 14 files. That relocates message types out of dapr_pb into new modules and breaks imports across the whole SDK. Separately, this repo's e2e defaults to DAPR_RUNTIME_VER=1.16.12, so a hard switch would fail its own CI, and 1.16.x is still actively patched. Since 1.17 and 1.18 still register alpha1 on both transports, the fallback never becomes dead code that silently breaks. This also matches what the Go, Python, and Java SDKs already ship for this exact RPC.

Things worth a careful look

  1. The vendored proto is hand-edited. The sanctioned path is bumping DAPR_VERSION in scripts/fetch-proto.js, which is what chore(proto): update protos and point Workflow to beta APIs dapr/js-sdk#531 did for workflow. I did not, because of the 14-file split described above. The backported RPC is byte-exact with upstream including option deprecated = true, so a later fetch at v1.17+ converges rather than conflicts. If maintainers would rather see the pin bump land first as its own PR, that is a reasonable ask and I am happy to rework.

  2. npx buf generate is not reproducible on main today. It resolves protoc-gen-es v2.11.0 to v2.15.0 and silently flips the committed stubs from ESM to CommonJS, about 750 lines of unrelated churn. I used a pinned config that reproduces the committed stubs exactly, keeping the codegen diff to the 43-line bulk publish delta. This looks like a pre-existing bug worth its own issue.

  3. E2E was not run. No live Dapr sidecar was available. Unit tests, typecheck, and build all pass. Note that CI e2e at 1.16.12 exercises the fallback path, not the stable path. Bumping DAPR_RUNTIME_VER to 1.17+ would cover stable but risks surfacing unrelated e2e failures, so I left it alone deliberately.

  4. HTTP 404 is ambiguous, since it is also how the sidecar reports an unknown pub/sub component. The fallback is therefore only remembered once the alpha1 endpoint has actually answered, which is the only real proof the runtime predates 1.17. There is a unit test covering this.

Issue reference

We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.

Please reference the issue this PR will close: dapr#786

(Fully qualified because this PR targets the fork. Retarget to dapr/js-sdk and it becomes Fixes #786.)

Checklist

Please make sure you've completed the relevant tasks for this PR, out of the following list:

  • Code compiles correctly (tsc --noEmit clean, npm run build succeeds)
  • Created/updated tests (11 new unit tests across gRPC and HTTP; 333 unit tests pass across 32 suites)
  • Extended the documentation (publishBulk JSDoc remarks plus a CHANGELOG entry)

Dapr promoted the bulk publish API out of alpha in runtime 1.17, but the JS
SDK still targeted the alpha1 variants over both transports. Move to the
stable API while keeping older sidecars working.

- gRPC: call BulkPublishEvent, falling back to BulkPublishEventAlpha1 when
  the sidecar answers UNIMPLEMENTED.
- HTTP: call v1.0/publish/bulk/{pubsubName}/{topic}, falling back to
  v1.0-alpha1 on a 404. A 404 also signals an unknown pub/sub component, so
  the downgrade is only remembered once the alpha1 endpoint has answered.
- Vendored proto: backport the stable BulkPublishEvent RPC and mark the
  alpha1 RPC deprecated, matching upstream dapr/dapr, and regenerate the
  affected stubs.

The public surface is unchanged: publishBulk keeps the same name, parameters
and return type. The fallback is remembered per client, so a pre-1.17 sidecar
costs at most one extra round trip, and it matches the behaviour the Go,
Python and Java SDKs already ship for this RPC.

Fixes dapr#786

Signed-off-by: Mark Gardner <mark.gardner@microsoft.com>
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.

feat(pubsub): Promote BulkPublishEventAlpha1 to stable BulkPublishEvent

1 participant