| # 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" |
| ``` |