| # gRPC Server Reflection Tutorial | |
| gRPC Server Reflection provides information about publicly-accessible gRPC | |
| services on a server, and assists clients at runtime to construct RPC requests | |
| and responses without precompiled service information. It is used by | |
| [gRPCurl](https://github.com/fullstorydev/grpcurl), which can be used to | |
| introspect server protos and send/receive test RPCs. | |
| ## Enable Server Reflection | |
| gRPC-go Server Reflection is implemented in package | |
| [reflection](https://github.com/grpc/grpc-go/tree/master/reflection). To enable | |
| server reflection, you need to import this package and register reflection | |
| service on your gRPC server. | |
| For example, to enable server reflection in `example/helloworld`, we need to | |
| make the following changes: | |
| ```diff | |
| --- a/examples/helloworld/greeter_server/main.go | |
| +++ b/examples/helloworld/greeter_server/main.go | |
| @@ -40,6 +40,7 @@ import ( | |
| "google.golang.org/grpc" | |
| pb "google.golang.org/grpc/examples/helloworld/helloworld" | |
| + "google.golang.org/grpc/reflection" | |
| ) | |
| const ( | |
| @@ -61,6 +62,8 @@ func main() { | |
| } | |
| s := grpc.NewServer() | |
| pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: sayHello}) | |
| + // Register reflection service on gRPC server. | |
| + reflection.Register(s) | |
| if err := s.Serve(lis); err != nil { | |
| log.Fatalf("failed to serve: %v", err) | |
| } | |
| ``` | |
| An example server with reflection registered can be found at | |
| `examples/features/reflection/server`. | |
| ## gRPCurl | |
| After enabling Server Reflection in a server application, you can use gRPCurl | |
| to check its services. gRPCurl is built with Go and has packages available. | |
| Instructions on how to install and use gRPCurl can be found at | |
| [gRPCurl Installation](https://github.com/fullstorydev/grpcurl#installation). | |
| ## Use gRPCurl to check services | |
| First, start the helloworld server in grpc-go directory: | |
| ```sh | |
| $ cd <grpc-go-directory>/examples | |
| $ go run features/reflection/server/main.go | |
| ``` | |
| output: | |
| ```sh | |
| server listening at [::]:50051 | |
| ``` | |
| After installing gRPCurl, open a new terminal and run the commands from the new | |
| terminal. | |
| **NOTE:** gRPCurl expects a TLS-encrypted connection by default. For all of | |
| the commands below, use the `-plaintext` flag to use an unencrypted connection. | |
| ### List services and methods | |
| The `list` command lists services exposed at a given port: | |
| - List all the services exposed at a given port | |
| ```sh | |
| $ grpcurl -plaintext localhost:50051 list | |
| ``` | |
| output: | |
| ```sh | |
| grpc.examples.echo.Echo | |
| grpc.reflection.v1alpha.ServerReflection | |
| helloworld.Greeter | |
| ``` | |
| - List all the methods of a service | |
| The `list` command lists methods given the full service name (in the format of | |
| \<package\>.\<service\>). | |
| ```sh | |
| $ grpcurl -plaintext localhost:50051 list helloworld.Greeter | |
| ``` | |
| output: | |
| ```sh | |
| helloworld.Greeter.SayHello | |
| ``` | |
| ### Describe services and methods | |
| - Describe all services | |
| The `describe` command inspects a service given its full name (in the format | |
| of \<package\>.\<service\>). | |
| ```sh | |
| $ grpcurl -plaintext localhost:50051 describe helloworld.Greeter | |
| ``` | |
| output: | |
| ```sh | |
| helloworld.Greeter is a service: | |
| service Greeter { | |
| rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply ); | |
| } | |
| ``` | |
| - Describe all methods of a service | |
| The `describe` command inspects a method given its full name (in the format of | |
| \<package\>.\<service\>.\<method\>). | |
| ```sh | |
| $ grpcurl -plaintext localhost:50051 describe helloworld.Greeter.SayHello | |
| ``` | |
| output: | |
| ```sh | |
| helloworld.Greeter.SayHello is a method: | |
| rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply ); | |
| ``` | |
| ### Inspect message types | |
| We can use the `describe` command to inspect request/response types given the | |
| full name of the type (in the format of \<package\>.\<type\>). | |
| - Get information about the request type | |
| ```sh | |
| $ grpcurl -plaintext localhost:50051 describe helloworld.HelloRequest | |
| ``` | |
| output: | |
| ```sh | |
| helloworld.HelloRequest is a message: | |
| message HelloRequest { | |
| string name = 1; | |
| } | |
| ``` | |
| ### Call a remote method | |
| We can send RPCs to a server and get responses using the full method name (in | |
| the format of \<package\>.\<service\>.\<method\>). The `-d <string>` flag | |
| represents the request data and the `-format text` flag indicates that the | |
| request data is in text format. | |
| - Call a unary method | |
| ```sh | |
| $ grpcurl -plaintext -format text -d 'name: "gRPCurl"' \ | |
| localhost:50051 helloworld.Greeter.SayHello | |
| ``` | |
| output: | |
| ```sh | |
| message: "Hello gRPCurl" | |
| ``` |