What Server Reflection Provides
The gRPC Server Reflection service (grpc.reflection.v1alpha, or grpc.reflection.v1 in newer implementations) is itself a gRPC service that a server can expose alongside its regular RPCs, letting any connected client ask 'what services do you host, what methods does each have, and what do the request and response messages look like' entirely at runtime, without the client needing a copy of the .proto file. This is what makes tools like grpcurl and Postman's gRPC client able to construct and send valid calls against a server they've never seen source code for, by walking the reflection API's ServerReflectionInfo bidirectional stream to fetch FileDescriptorProto definitions on demand.
Cricket analogy: Like a stadium's scoreboard broadcasting the full team lineup and batting order to anyone in the stands without needing the official team sheet, gRPC reflection broadcasts a server's full service and method list to any connected client without needing the .proto file.
Enabling Reflection on a Server
Enabling reflection in Go is a one-line addition — import google.golang.org/grpc/reflection and call reflection.Register(grpcServer) after creating your grpc.Server but before calling Serve — which registers the reflection service alongside whatever business services you've already registered via RegisterXxxServer. Because reflection literally hands out your entire API's method signatures and message schemas to anyone who can open a connection, most teams gate it behind an environment check so it's registered in development and staging but conditionally skipped (or placed behind auth) in production builds.
Cricket analogy: Like a franchise deciding to publish full player contract details during preseason friendlies but keep them confidential during the actual league auction, teams enable reflection.Register in dev and staging builds but gate or skip it in production.
import "google.golang.org/grpc/reflection"
srv := grpc.NewServer()
pb.RegisterInventoryServiceServer(srv, &inventoryServer{})
if os.Getenv("ENV") != "production" {
reflection.Register(srv)
}Using grpcurl for Ad-Hoc Testing
grpcurl is the gRPC equivalent of curl for HTTP: grpcurl -plaintext localhost:50051 list enumerates every service the server exposes via reflection, grpcurl -plaintext localhost:50051 describe mypackage.MyService.MyMethod prints that method's request and response message shape, and grpcurl -plaintext -d '{\"id\": 42}' localhost:50051 mypackage.MyService/GetItem actually invokes the RPC with a JSON-encoded payload and prints the JSON-encoded response. Dropping -plaintext and instead passing -cacert or -insecure controls how grpcurl handles TLS, mirroring the same trust decisions a real gRPC client library would make when dialing a TLS-secured server.
Cricket analogy: Like a commentator calling out the field placement and bowling figures live without needing to read the official scorebook, grpcurl list and describe surface a server's services and method shapes live without a .proto file in hand.
# List every service the server exposes
grpcurl -plaintext localhost:50051 list
# Describe a specific method's request/response shape
grpcurl -plaintext localhost:50051 describe inventory.InventoryService.GetItem
# Invoke the RPC with a JSON payload
grpcurl -plaintext -d '{"id": 42}' localhost:50051 inventory.InventoryService/GetItemgrpcurl mirrors the everyday curl workflow for REST: grpcurl -plaintext host:port list is like browsing an API's route table, describe is like reading a single endpoint's schema, and -d '{...}' invoke is like sending a test POST body — except every call is validated against the server's live Protobuf schema instead of guesswork.
Reflection in Production: Risks and Alternatives
Because reflection exposes your complete API surface — every method name, every field, every nested message type — to anyone who can reach the port, it's a meaningful information-disclosure risk on a public-facing production endpoint, roughly equivalent to leaving OpenAPI's swagger.json unauthenticated on a REST API. The safer production pattern is to disable reflection entirely and instead distribute the compiled FileDescriptorSet (via buf build -o or protoc --descriptor_set_out) to the specific teams and tools that need it, letting grpcurl target the server with grpcurl -protoset my.protoset instead of relying on the server volunteering its own schema.
Cricket analogy: Like a team leaving its complete strategy playbook lying in the open dressing room where any rival could photograph it, leaving reflection enabled on a public-facing production server exposes the entire API surface to anyone who can reach the port.
Never leave server reflection enabled on a public-facing production endpoint without authentication in front of it — it hands out your complete API surface (every service, method, and message field) to anyone who can open a TCP connection to the port, the gRPC equivalent of leaving swagger.json unauthenticated.
- Server reflection is itself a gRPC service exposing method/message schemas at runtime, without needing .proto files.
- reflection.Register(server) is a one-line addition in Go, typically enabled in dev/staging.
- grpcurl uses reflection (or a supplied protoset) to list, describe, and invoke RPCs from the command line.
- grpcurl list and describe explore a server's API surface; -d and invoke send an actual test call.
- -plaintext controls whether grpcurl expects TLS, mirroring real client trust decisions.
- Reflection on a public production endpoint discloses the complete API surface to any connecting client.
- Shipping a compiled FileDescriptorSet (protoset) is a safer alternative to leaving reflection enabled in production.
Practice what you learned
1. What does the gRPC Server Reflection service provide to a client?
2. In Go, where should reflection.Register(grpcServer) typically be called?
3. What does `grpcurl -plaintext localhost:50051 describe mypkg.MyService.MyMethod` do?
4. Why is enabling reflection on an unauthenticated public production endpoint risky?
5. What is a safer production alternative to enabling live server reflection?
Was this page helpful?
You May Also Like
gRPC Authentication with TLS
How gRPC uses TLS and mutual TLS to secure transport, and how call credentials layer token-based authorization on top for production services.
gRPC Interceptors
How to use gRPC interceptors to implement cross-cutting logic like logging, authentication, retries, and tracing without touching individual handlers.
gRPC-Gateway for REST Compatibility
How grpc-gateway generates a REST/JSON reverse-proxy from annotated .proto files so browsers and legacy clients can reach a gRPC-only backend.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics
Web DevelopmentNext.js Study Notes
JavaScript · 30 topics