Expand description
gRPC server reflection for connectrpc.
Wire-compatible with grpc.reflection.v1.ServerReflection and its
v1alpha predecessor, so grpcurl, buf curl, Postman, grpcui,
and every other reflection-aware client just works — over gRPC,
gRPC-Web, and the Connect protocol alike.
§Quick start
Emit a descriptor set from your build script alongside code generation:
// build.rs
connectrpc_build::Config::new()
.files(&["proto/app.proto"])
.includes(&["proto/"])
.emit_descriptor_set("app.fds.bin")
.compile()
.unwrap();then embed it and mount the service:
use connectrpc::Router;
use connectrpc_reflection::{Reflector, install};
// In real code: include_bytes!(concat!(env!("OUT_DIR"), "/app.fds.bin"))
let reflector = Reflector::from_descriptor_set_bytes(descriptor_set_bytes()).unwrap();
let router = install(Router::new(), reflector);install registers both protocol versions; use the generated
extension traits directly if you want only one (and see
Request limits below for the extra call that needs).
Alternatively, when your buffa codegen has reflection enabled, skip the build-script step and serve straight from the generated package’s descriptor pool:
let reflector =
Reflector::from_descriptor_pool(myapp::proto::descriptor_pool().clone()).unwrap();The bytes path needs only emit_descriptor_set — reflection codegen
is not required — and answers with the compiler’s original
per-file descriptor bytes; the pool path re-encodes (semantically
faithful, unknown fields preserved). See Reflector for the
trade-off.
§Request limits
A ServerReflectionRequest is a host plus one symbol, file name or type
name, so the reflection routes do not need the multi-megabyte request
ceiling a connectrpc service allows by default. This crate sizes them
to MAX_REQUEST_BYTES (16 KiB) per request message through per-route
Limits — see request_limits for the exact
profile; ServerReflectionInfo is a bidirectional stream, so the bound
is per message rather than per call. A larger message ends the stream
with resource_exhausted. The profile replaces the service-wide limits
on these routes, whether those are looser or tighter.
installappliesrequest_limitsfor you, to both versions.- Registering a
ReflectionServiceany other way — one version through the generatedServerReflectionExt::register, orRouter::add_service— does not, so follow it withapply_request_limits(router,request_limits()); it covers whichever versions are mounted. - To tune the reflection routes specifically, call
apply_request_limitswith your ownLimitsafter either path; the later call wins.
use connectrpc::{Limits, Router};
use connectrpc_reflection::{Reflector, apply_request_limits, install};
let reflector = Reflector::from_descriptor_set_bytes(descriptor_set_bytes()).unwrap();
let router = install(Router::new(), reflector);
// Optional: hold reflection messages to 1 KiB instead of the bundled 16 KiB.
let router = apply_request_limits(router, Limits::default().with_max_message_size(1024));§What gets exposed
Everything in the descriptor set: all files, their transitive
imports, and every service compiled into it — whether or not the
corresponding handlers are mounted on the router. Use
Reflector::with_services to curate the advertised service list,
and Reflector::service_names to inspect it. Build the set from
the same protos you serve, and remember that reflection
intentionally publishes your schema: gate or omit the service on
deployments where that is not wanted.
The reflection service is self-describing: queries about
grpc.reflection.* fall back to the crate’s own descriptors, and
ListServices advertises the reflection services alongside yours.
This matches grpc-go (where the reflection proto is always
registered) and is what schema-free callers like buf curl need to
invoke ServerReflectionInfo directly. Use
Reflector::with_services to advertise a different list — the
override is verbatim, so omitting the reflection names de-lists them
(they stay resolvable as symbols).
§Cargo features
client(on by default) — re-exports the generatedServerReflectionClientfor querying a reflection server (integration tests, CLI tooling). Pulls inconnectrpc’sclientfeature; server-only deployments opt out withdefault-features = false.
Modules§
- wire
- Re-exports of the generated
grpc.reflection.*wire types — request and response messages, their oneof modules, and the methodSpecconstants. Everything a downstream crate needs to driveServerReflectionClient(gated on theclientfeature) or inspect responses without regenerating the protos.
Structs§
- Reflection
Service - gRPC-compatible server reflection service backed by a
Reflector. - Reflector
- Descriptor index serving gRPC server reflection queries.
- Server
Reflection Client client - Generated client for querying a
grpc.reflection.v1.ServerReflectionserver. Client for this service.
Enums§
- Reflection
Error - Errors from building a
Reflector.
Constants§
- FILE_
DESCRIPTOR_ SET - The wire-format
FileDescriptorSetfor this crate’s protos (grpc.reflection.v1andv1alpha, from the public Buf Schema Registry’sbuf.build/grpc/grpcmodule). - MAX_
REQUEST_ BYTES - The largest request message, after decompression, the reflection routes
accept under
request_limits: 16 KiB. - SERVER_
REFLECTION_ SERVICE_ NAME - Fully-qualified name of the v1 reflection service. Full service name for this service.
- SERVER_
REFLECTION_ V1ALPHA_ SERVICE_ NAME - Fully-qualified name of the v1alpha reflection service. Full service name for this service.
Traits§
- Server
Reflection - Generated v1 service trait and registration extension, for callers that mount a single protocol version by hand:
- Server
Reflection Ext - Generated v1 service trait and registration extension, for callers that mount a single protocol version by hand:
- Server
Reflection V1alpha - Generated v1alpha service trait and registration extension, renamed to avoid colliding with the v1 items, for callers that mount the legacy protocol version by hand. Server trait for ServerReflection.
- Server
Reflection V1alpha Ext - Generated v1alpha service trait and registration extension, renamed to avoid colliding with the v1 items, for callers that mount the legacy protocol version by hand. Extension trait for registering a service implementation with a Router.
Functions§
- apply_
request_ limits - Set whichever of the
v1andv1alphareflection routes are registered onroutertolimits, replacing the service-wide limits for them (whether looser or tighter). - install
- Register both protocol versions (
v1andv1alpha) on a router. - request_
limits - The per-route
Limitsthis crate sets on its routes: message size capped atMAX_REQUEST_BYTES(and the request body, which only governs non-streaming calls, at that plus the 5-byte envelope), decode budget left at theconnectrpcdefault.