Skip to content

Add anthropics/buffa and anthropics/connect-rust plugins#2334

Open
iainmcgin wants to merge 1 commit into
bufbuild:mainfrom
iainmcgin:add-connectrpc-rust-plugin
Open

Add anthropics/buffa and anthropics/connect-rust plugins#2334
iainmcgin wants to merge 1 commit into
bufbuild:mainfrom
iainmcgin:add-connectrpc-rust-plugin

Conversation

@iainmcgin
Copy link
Copy Markdown

@iainmcgin iainmcgin commented Mar 17, 2026

Adds the protoc-gen-buffa and protoc-gen-connect-rust plugins for Rust protobuf and ConnectRPC code generation, under the new top-level anthropics org as requested in earlier review.

This PR contains both plugins, so it can land on its own. (It was originally stacked on #2333, which adds anthropics/buffa alone — #2333 is now superseded by this PR.)

buffa

buffa is a zero-copy Rust Protobuf implementation with:

  • Editions support (2023/2024) and full proto2/proto3 coverage
  • Zero-copy view types - borrowed &str/&[u8] field access without owned allocation
  • no_std + alloc compatible
  • Proto3 JSON mapping with serde integration
  • Conformance: passes the protobuf conformance suite (5539 binary+JSON tests, 0 expected failures)

Crates on crates.io: buffa, buffa-types, protoc-gen-buffa.

protoc-gen-buffa generates message types. With file_per_package=true (set in opts), it emits one <dotted.package>.rs file per proto package: foo/v1/bar.proto and foo/v1/baz.proto both land in foo.v1.rs. No subdirectories, no mod.rs. This matches the prost/tonic filename convention the BSR Rust SDK lib.rs synthesis already understands.

connect-rust

connect-rust is a Tower-based Rust implementation of the ConnectRPC protocol:

  • Three protocols: Connect, gRPC, gRPC-Web - same service impl handles all three
  • Full conformance: 3600 server tests, 2580/1454/2838 client tests across Connect/gRPC/gRPC-Web
  • Zero-copy request handling via buffa view types - request.name is a &str borrow into the decoded buffer
  • Tower integration: composes with axum, hyper, tower middleware

Crates on crates.io: connectrpc, connectrpc-codegen, connectrpc-build.

protoc-gen-connect-rust emits service stubs only - server traits, typed clients, monomorphic dispatchers. Message types come from buf.build/anthropics/buffa (declared in deps:). Generated stubs reference message types via absolute Rust paths configured with extern_path. It also takes file_per_package, mirroring the anthropics/buffa opt.

Dockerfile note: the protoc-gen-connect-rust binary is a [[bin]] target inside the connectrpc-codegen crate, so cargo install connectrpc-codegen is what produces it.

extern_path handling

protoc-gen-connect-rust needs an extern_path=.=<rust_path> (or shorthand buffa_module=<rust_path>) catch-all so it knows where the buffa-generated message types live. Per @stefanvanburen's review, opts: is left as just [file_per_package] — the BSR injects extern_path from the deps: chain at SDK build time using the same prost syntax as tonic.

The standalone test harness has no dep chain, so this PR adds a testOverrideOptions entry passing a placeholder extern_path=.=crate — the same pattern neoeinstein-prost-crate (no_features) and neoeinstein-tonic (no_include) use to make their isolated test runs succeed without affecting production opts.

plugin.sum files for both plugins (eliza and petapis) are checked in; make test PLUGINS="anthropics/buffa anthropics/connect-rust" passes.

@bufdev
Copy link
Copy Markdown
Member

bufdev commented Mar 19, 2026

#2333 (comment)

@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from 61b03f3 to eca199a Compare April 2, 2026 21:24
@iainmcgin iainmcgin changed the title Add connectrpc/rust plugin v0.2.0 Add anthropics/connect-rust plugin v0.2.0 Apr 2, 2026
@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from eca199a to f42cc7a Compare April 2, 2026 21:36
@iainmcgin iainmcgin changed the title Add anthropics/connect-rust plugin v0.2.0 Add anthropics/connect-rust plugin v0.3.1 Apr 2, 2026
@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from f42cc7a to 92259e7 Compare April 3, 2026 01:20
@iainmcgin iainmcgin marked this pull request as ready for review April 3, 2026 15:54
@iainmcgin
Copy link
Copy Markdown
Author

changed to crate ref instead of github ref 👍

@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from 92259e7 to 314f1da Compare April 3, 2026 18:34
@iainmcgin iainmcgin changed the title Add anthropics/connect-rust plugin v0.3.1 Add anthropics/connect-rust plugin v0.3.2 Apr 3, 2026
@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from 314f1da to b60cff4 Compare April 3, 2026 18:55
Comment on lines +35 to +40
# The plugin accepts `extern_path=.=<rust_path>` (or the shorthand
# `buffa_module=<rust_path>`) to tell it where the buffa-generated message
# types live. BSR should inject this based on the buffa dep's SDK crate
# name, same as tonic receives extern_path for its prost dep. Leaving
# opts empty here; please advise if an explicit entry is needed.
opts: []
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be fine to leave this empty, and the BSR will figure out extern_path settings using the prost syntax 👍.

# https://github.com/anthropics/connect-rust/blob/v0.3.2/connectrpc/Cargo.toml
- name: "connectrpc"
req: "0.3.2"
default_features: true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

silly non-expert-in-rust question: I see the default features; those don't include the tls feature, but is that just something that is "enabled" by having the various "deps" in the sub-features installed? (Mostly trying to confirm that someone consuming this generated SDK could still use the TLS features.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[claude code] Yes — Cargo features are additive and unified per-crate across the dependency graph. The generated SDK crate only needs connectrpc's default features for the generated code to compile, so that's all it declares. A consumer who wants TLS adds their own direct dependency in their application's Cargo.toml:

connectrpc = { version = "0.4", features = ["tls"] }

Cargo then compiles connectrpc once with the union of features requested by both the SDK crate and the application, so tls (and client-tls / server-tls / any other optional feature) is fully available. Same model the tonic SDK crates use — the SDK doesn't gate runtime features.

@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from b60cff4 to 114550b Compare May 11, 2026 15:32
@iainmcgin iainmcgin changed the title Add anthropics/connect-rust plugin v0.3.2 Add anthropics/connect-rust plugin v0.4.2 May 11, 2026
@iainmcgin
Copy link
Copy Markdown
Author

[claude code] Updated to protoc-gen-connect-rust v0.4.2 with file_per_package set in opts and the deps plugin reference bumped to anthropics/buffa:v0.5.2. The branch is now stacked on #2333.

I haven't been able to check in plugin.sum files yet — generation fails without an extern_path/buffa_module opt, and I'm not sure what value to put there. The PR description has the details, but in short: I need to know whether the BSR cargo SDK pipeline composites a dep chain (buffa + connect-rust) into one crate or separate crates, and whether it injects an extern_path opt for the dep's types the way I'd assumed it does for tonic→prost. @stefanvanburen / @pkwarren — could you confirm, or point me at a doc/example?

@iainmcgin iainmcgin requested a review from stefanvanburen May 11, 2026 21:31
@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from 1bbdd79 to 85561d7 Compare May 12, 2026 20:58
@iainmcgin
Copy link
Copy Markdown
Author

[claude code] Pushed an update — plugin.sum files are now checked in and the branch is rebased onto current main.

Summary of changes since the last push:

  • Rebased onto main and bumped both Dockerfiles to the current base images from .github/docker/: docker/dockerfile:1.23, rust:1.95.0-alpine3.23, gcr.io/distroless/static-debian13.
  • Checked in plugin.sum for eliza and petapis.
  • Added a testOverrideOptions entry for buf.build/anthropics/connect-rust. The standalone test harness runs each plugin in isolation with only the opts declared in buf.plugin.yaml, so it has no way to derive an extern_path from the deps: chain the way the BSR SDK pipeline does. The override passes a placeholder extern_path=.=crate catch-all so codegen succeeds — same pattern neoeinstein-prost-crate (no_features) and neoeinstein-tonic (no_include) use. Production opts: is left as just [file_per_package] per @stefanvanburen's earlier guidance that the BSR injects extern_path automatically.

The "Open question: extern_path injection — plugin.sum not yet checked in" section of the PR description is now stale; happy to edit it down once you've had a look.

@iainmcgin iainmcgin changed the title Add anthropics/connect-rust plugin v0.4.2 Add anthropics/buffa and anthropics/connect-rust plugins May 12, 2026
Adds two new plugins under the anthropics top-level org for Rust
protobuf and ConnectRPC code generation.

protoc-gen-buffa (v0.5.2) generates Rust message types using buffa, a
zero-copy Protobuf implementation with editions support, no_std
compatibility, and proto3 JSON mapping. With file_per_package=true it
emits one <dotted.package>.rs per proto package, matching the
prost/tonic filename convention the BSR Rust SDK lib.rs synthesis
expects.

protoc-gen-connect-rust (v0.4.2) generates ConnectRPC service stubs
only — server traits, typed clients, monomorphic dispatchers — and
declares buf.build/anthropics/buffa as a plugin dep for message types.
Generated stubs reference message types via absolute Rust paths
configured with extern_path, which the BSR injects from the deps:
chain at SDK build time. The standalone test harness has no dep chain,
so a testOverrideOptions entry passes a placeholder extern_path=.=crate
catch-all — the same pattern neoeinstein-prost-crate (no_features) and
neoeinstein-tonic (no_include) use to make isolated test runs succeed
without affecting production opts.

The connect-rust SDK crate depends on buffa-types (with the json
feature) so service stubs whose request/response is a well-known type
can reference ::buffa_types::google::protobuf::... and so connectrpc's
Router bounds (Message + Serialize + DeserializeOwned) are satisfied
for the Connect protocol's JSON codec.
@iainmcgin iainmcgin force-pushed the add-connectrpc-rust-plugin branch from 85561d7 to 9c75f5b Compare May 12, 2026 22:07
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.

3 participants