connect_rpc_httpx is a Connect RPC client for Ruby that speaks the Connect protocol over httpx. Its companion protoc plugin, protoc-gen-connect-ruby, generates the clients from your .proto files: each service becomes a plain Ruby class with one method per RPC, along with an RBS signature so Steep can check the calls.
Unary RPCs, client and server streams, and half-duplex bidirectional streams are supported, and checked against the official Connect conformance suite.
- A client per service, in the module protoc's Ruby generator puts the messages in, with snake_case methods
- Server streams yield messages to a block or as an Enumerable; client streams take any Enumerable, including a lazy one
- RBS signatures for every generated client, typed against your message classes
- One client instance can be shared between threads: it is frozen after construction, and httpx pools its connections
- Connect GET for RPCs marked
idempotency_level = NO_SIDE_EFFECTS, so caches and proxies can serve them - proto and JSON codecs, over HTTP/1.1 or HTTP/2, with or without TLS
- Every failure raises
ConnectRpcHttpx::Errorwith the Connect code, details, and response metadata
This repository holds two gems:
| Gem | Needed | What |
|---|---|---|
protoc_gen_connect_ruby |
where code is generated | the protoc-gen-connect-ruby plugin for protoc and buf |
connect_rpc_httpx |
where the clients run | the runtime: client base class, codecs, errors |
Neither is released to RubyGems.org yet. Both require Ruby 3.4 or later.
# Gemfile
gem "protoc_gen_connect_ruby", group: :development
gem "connect_rpc_httpx"The plugin runs next to protoc's built-in Ruby generator, which writes the message classes:
# buf.gen.yaml
version: v2
plugins:
- protoc_builtin: ruby
out: lib/gen
- local: [bundle, exec, protoc-gen-connect-ruby]
out: lib/genbuf generate proto
For proto/acme/greet/v1/greet.proto, this writes greet_pb.rb, greet_connect.rb and greet_connect.rbs under lib/gen/acme/greet/v1/. With protoc instead of buf: protoc --ruby_out=lib/gen --connect-ruby_out=lib/gen acme/greet/v1/greet.proto.
Generated files require each other by path, as protoc's Ruby output does, so the output directory goes on the load path:
$LOAD_PATH.unshift(File.expand_path("lib/gen", __dir__))
require "acme/greet/v1/greet_connect"
client = Acme::Greet::V1::GreetServiceClient.new("https://api.example.com", timeout: 5)
response = client.greet(name: "Ruby")
response.greetingThe connect_rpc_httpx README covers client options, per-call headers and deadlines, response metadata and errors. The protoc_gen_connect_ruby README covers the generated code and its type signatures.
- Full-duplex bidirectional streaming, the gRPC and gRPC-Web protocols, and request compression are not implemented. A bidirectional RPC sends all of its requests before reading responses.
- A call blocks its thread and cannot be cancelled from another one. A stream is cancelled by leaving its iteration.
- Type-checking calls into generated clients needs RBS for the message classes too, which this plugin does not write.
- connect_rpc_rails serves Connect unary RPCs from a Rails app, for the server side.
mise install
hk install
bin/setup
bundle exec rake # specs and steep, for both gems
mise run conformance # the Connect conformance suite, see conformance/
bundle exec rake yard # API docs into doc/yard (or rake rdoc)DESIGN.md describes how the pieces fit together.
Apache-2.0. Copyright 2026 IVRy Inc. See LICENSE.