62. gRPC Reflection for Tools like `grpcurl`
62. gRPC Reflection for Tools like grpcurl
gRPC has become one of the de facto standards in modern microservices development. With advantages such as fast HTTP/2-based communication, strong contracts powered by Protobuf, and even bidirectional streaming, it is no surprise that gRPC has been widely adopted by large companies. Yet, despite all of these benefits, gRPC comes with a unique challenge that often surfaces when you need to debug or explore a gRPC API. One of them: how do we interact with or perform introspection on a gRPC API without needing the .proto file?
This is exactly where the gRPC Reflection feature comes in, opening the door for tools like grpcurl
that can automatically inspect a running gRPC service without having the Protofile locally. This article discusses gRPC Reflection, how it works, and an example of using it with grpcurl. I’ll also include a flow diagram using mermaid and a table to help your understanding.
What Is gRPC Reflection?
Put simply, gRPC Reflection is a server extension that allows clients to query metadata about the services, messages, and methods exposed by a gRPC server. This reflection is extremely helpful when we want to:
- Explore an API dynamically (for example, checking which methods are available),
- Support tooling such as grpcurl, Postman, or certain IDEs,
- Manually verify system integration without proto files.
gRPC Reflection works by adding a special service to the gRPC server, which automatically reads and shares the available service metadata with clients (in a safe manner, of course).
The Scenario Without Reflection
In the real world, when you need to debug a gRPC endpoint, the first thing you need is naturally the proto file used by the encoder/decoder along with the endpoint map. However, this file is often:
- Not directly available,
- A different version from the deployment,
- Stored in a private repo,
- Or simply forgotten and out of sync.
Without the right proto file, tools like grpcurl, Evans, and even the VSCode plugin will struggle to interact with the server.
The Scenario With Reflection
By enabling Reflection, we can use a tool like grpcurl in a protoless way—you only need to know the endpoint address! These tools can discover methods, services, and fields and send requests without any manual proto.
How gRPC Reflection Works (mermaid Diagram)
Let’s visualize the request flow between grpcurl, the Reflection Service, and the Actual Service using the following mermaid diagram:
sequenceDiagram
participant User
participant grpcurl
participant ReflectionService
participant ActualService
User->>grpcurl: Mengetik perintah grpcurl (tanpa proto)
grpcurl->>ReflectionService: Query metadata & list service
ReflectionService-->>grpcurl: Return daftar service & protos
grpcurl->>ActualService: Eksekusi RPC call berbasis hasil protocol reflection
ActualService-->>grpcurl: Response RPC
grpcurl-->>User: Tampilkan response
Example: Enabling Reflection in gRPC Go
Let’s discuss how to enable gRPC Reflection in Go. Suppose we have a simple service like the following:
1// helloworld.proto
2service Greeter {
3 rpc SayHello (HelloRequest) returns (HelloReply) {}
4}We’ll add reflection during the server initialization:
1package main
2
3import (
4 "net"
5 "google.golang.org/grpc"
6 "google.golang.org/grpc/reflection"
7 pb "example.com/helloworld" // package generated from the proto
8)
9
10func main() {
11 lis, _ := net.Listen("tcp", ":50051")
12 s := grpc.NewServer()
13 pb.RegisterGreeterServer(s, &server{})
14 // Enable Reflection right here
15 reflection.Register(s)
16
17 s.Serve(lis)
18}Just a single line: reflection.Register(s).
Exploring the Service with grpcurl
Even without a proto file, we can still explore the API via grpcurl:
1# List all available services
2grpcurl -plaintext localhost:50051 list
3
4# List all methods on 'Greeter'
5grpcurl -plaintext localhost:50051 list Greeter
6
7# View the description of the SayHello method
8grpcurl -plaintext localhost:50051 describe Greeter.SayHello
9
10# Call the RPC
11echo '{"name":"World"}' | grpcurl -plaintext -d @ localhost:50051 Greeter/SayHelloExample Output:
1Greeter
2grpc.reflection.v1alpha.ServerReflection1Greeter.SayHello1rpc SayHello (HelloRequest) returns (HelloReply);1{
2 "message": "Hello, World"
3}-plaintext option is used when the server does not use TLS.Table: Comparison With and Without Reflection
| Feature | Without Reflection | With Reflection |
|---|---|---|
| List service/method | Requires proto file | Works directly |
| Describe field/parameter | Not possible | Possible |
| Testing/dummy call | Requires proto schema | No manual proto needed |
| Static code generation | Requires proto | Requires proto |
| Extra security | More private | Needs access control |
Potential Security Risks
Because Reflection exposes your API metadata, only enable this feature:
- in development or staging environments, DO NOT use it in production unless truly necessary,
- Apply ACLs at the Firewall/Authentication level,
- Use middleware/access control to restrict who is allowed to perform reflection.
Advanced: Reflection in gRPC with TLS
If your server uses TLS, grpcurl must be told about the CA credential, client certificate, and so on. For example:
1grpcurl -cacert ca.pem -cert client.pem -key client-key.pem mydomain:443 listExtension & Ecosystem
Besides grpcurl, there are other tools such as Evans (a CLI REPL for gRPC), Postman (a beta version of the gRPC feature), and even REST Gateway generators that become even more powerful with Reflection.
Simulation: Introspecting a New Service
Imagine your colleague deploys a new microservice, but you didn’t receive its proto. Use:
1grpcurl -plaintext 10.0.0.1:9000 listExample output:
1UserService
2grpc.reflection.v1alpha.ServerReflectionThen continue:
1grpcurl -plaintext 10.0.0.1:9000 describe UserService.GetProfilegrpcurl will report the fields, types, and message structure of that endpoint, so you can craft requests even without the original source proto.
Conclusion
gRPC Reflection is a powerful tool for improving the exploration, debugging, and testing of gRPC-based services. Enabling it is very easy (just a single line in your code), and it immediately opens the way for dynamic interaction through tooling like grpcurl. While it is highly convenient, use it wisely and prioritize security by restricting access in sensitive environments.
In the era of observability and shifting-left debugging, features like gRPC Reflection not only make developers’ work easier but also speed up the development process and integration between teams.
Happy experimenting with grpcurl — the Swiss army knife for gRPC debugging! 🚀
References: