connect2axum

Generate REST and/or WebSocket endpoint wrappers over ConnectRPC services. Additionally, generate OpenAPI docs for REST endpoints and AsyncAPI docs for WebSocket endpoints.
Install
This installs:
protoc-gen-connect2restprotoc-gen-connect2wsprotoc-gen-connect2openapiprotoc-gen-connect2asyncapi
connect2axum 0.4 and connect2axum-codegen 0.5 target Buffa 0.9 and
ConnectRPC 0.9. When upgrading from upstream versions before 0.9, regenerate
the Buffa, ConnectRPC, and connect2axum bindings together. Service implementations receive
ServiceRequest<'_, Request> for unary and server-streaming calls, and
InboundStream<Request> (items of StreamMessage<Request>) for client and
bidirectional streaming calls. Read stream-item fields through .view() or
the generated accessor methods.
Version 0.4 removes JsonCompatibleView and json_compatible_view. Use
json_view for response views with a ProtoJSON Serialize implementation,
or return an owned message. json_owned_view remains the input helper for
decoding incoming JSON into an OwnedView.
Domain-owned Responses
An application can keep its own response types and borrow their fields only
while encoding. Implement ConnectRPC's Encodable<Message> for the domain
type and use connect2axum::json_view around a temporary Buffa view:
use Bytes;
use ;
use SharedStr;
// HelloReply and HelloReplyView are the generated message and view types.
The stream owns each Greeting, so it can cross task/channel boundaries.
The view borrows its fields only during encoding; no generated owned
HelloReply or intermediate protobuf buffer is needed to produce JSON.
This does not require SharedStr to implement Buffa field traits because the
generated view uses &str.
json_view serializes JSON directly through the view's Serialize impl and
delegates other codecs to its Encodable impl. Enable Buffa JSON generation
for the view. Both implementations must represent the same protobuf message;
an arbitrary domain struct's derived serde is not necessarily ProtoJSON.
The same response item works with Connect/gRPC, REST, and JSON WebSocket
adapters. See the WebSocket streaming example
for a complete implementation and transport tests.
Return an owned message when registered protobuf extensions must appear in JSON: Buffa's generated view serializer omits those extensions. Direct view encoding can still allocate output buffers or temporary view containers; it does not guarantee allocation-free serialization.
Nested Fields
Path variables may bind a field inside singular messages, such as
get: "/symbols/{datasource.symbol.ticker}". The rest of datasource still
comes from the body or query; the path value overrides only that field.
Query parameters accept dotted paths into nested messages, using protobuf or
JSON field names: ?datasource.symbol.exchange=NASDAQ&datasource.workspaceName=demo.
Plugin Options
Options are passed as comma-separated name=value pairs in buf.gen.yaml.
plugins:
- local: protoc-gen-connect2rest
out: src/generated/connect2axum
opt:
- buffa_module=crate::proto
- connect_module=crate::connect
- local: protoc-gen-connect2ws
out: src/generated/connect2axum
opt:
- buffa_module=crate::proto
- connect_module=crate::connect
- local: protoc-gen-connect2openapi
out: src/generated/openapi
strategy: all
opt:
- config=connect2openapi.yaml
- local: protoc-gen-connect2asyncapi
out: src/generated/asyncapi
strategy: all
opt:
- config=connect2asyncapi.yaml
Active Options
| Option | Default | Used By | Purpose |
|---|---|---|---|
buffa_module |
crate::proto |
REST, WS | Rust module root where Buffa generated messages are available. |
connect_module |
crate::connect |
REST, WS | Rust module root where Connect Rust generated service traits are available. |
runtime_module |
::connect2axum |
REST, WS | Rust path to the runtime helper crate/module. |
streaming_content_type |
application/x-ndjson |
REST | REST streaming response content type. |
suppress_pkg_prefix |
true |
OpenAPI, AsyncAPI | Omit protobuf package prefixes from document component names and references. |
value_suffix |
__ |
REST, WS | Suffix for generated local bindings to avoid collisions with request fields. |
type_suffix |
__ |
REST | Suffix for generated DTO type names. |
body_message_suffix |
Body |
REST | Suffix for generated body DTOs. |
query_message_suffix |
Query |
REST | Suffix for generated query DTOs. |
OpenAPI Generator
protoc-gen-connect2openapi wraps grpc-gateway's
protoc-gen-openapiv3, then patches the generated document for connect2axum
REST behavior. It supports output, config, openapiv3_bin,
openapiv3_opt, streaming_content_type, and suppress_pkg_prefix plugin
options.
See docs/openapi-generator.md for config format and backend details.
AsyncAPI Generator
protoc-gen-connect2asyncapi emits AsyncAPI v3.1 JSON for the JSON WebSocket
routes generated by protoc-gen-connect2ws. It supports output, config,
server_url, default_content_type, and suppress_pkg_prefix plugin options.
See docs/asyncapi-generator.md for document shape and config details.
WebSocket Notes
protoc-gen-connect2ws only generates JSON WebSocket routes for streaming RPCs.
Unary RPCs stay REST/Connect-only. Client and bidirectional request streams end
with an empty text frame so the socket can remain open for any response frames.