1# gRPC Server Reflection Tutorial
2
3gRPC Server Reflection provides information about publicly-accessible gRPC
4services on a server, and assists clients at runtime to construct RPC requests
5and responses without precompiled service information. It is used by gRPC CLI,
6which can be used to introspect server protos and send/receive test RPCs.
7
8## Enable Server Reflection
9
10gRPC-go Server Reflection is implemented in package
11[reflection](https://github.com/grpc/grpc-go/tree/master/reflection). To enable
12server reflection, you need to import this package and register reflection
13service on your gRPC server.
14
15For example, to enable server reflection in `example/helloworld`, we need to
16make the following changes:
17
18```diff
19--- a/examples/helloworld/greeter_server/main.go
20+++ b/examples/helloworld/greeter_server/main.go
21@@ -40,6 +40,7 @@ import (
22        "google.golang.org/grpc"
23        pb "google.golang.org/grpc/examples/helloworld/helloworld"
24+       "google.golang.org/grpc/reflection"
25 )
26
27 const (
28@@ -61,6 +62,8 @@ func main() {
29        }
30        s := grpc.NewServer()
31        pb.RegisterGreeterServer(s, &server{})
32+       // Register reflection service on gRPC server.
33+       reflection.Register(s)
34        if err := s.Serve(lis); err != nil {
35                log.Fatalf("failed to serve: %v", err)
36        }
37```
38
39An example server with reflection registered can be found at
40`examples/features/reflection/server`.
41
42## gRPC CLI
43
44After enabling Server Reflection in a server application, you can use gRPC CLI
45to check its services. gRPC CLI is only available in c++. Instructions on how to
46use gRPC CLI can be found at
47[command_line_tool.md](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md).
48
49To build gRPC CLI:
50
51```sh
52git clone https://github.com/grpc/grpc
53cd grpc
54git submodule update --init
55make grpc_cli
56cd bins/opt # grpc_cli is in directory bins/opt/
57```
58
59## Use gRPC CLI to check services
60
61First, start the helloworld server in grpc-go directory:
62
63```sh
64$ cd <grpc-go-directory>
65$ go run examples/features/reflection/server/main.go
66```
67
68Open a new terminal and make sure you are in the directory where grpc_cli lives:
69
70```sh
71$ cd <grpc-cpp-dirctory>/bins/opt
72```
73
74### List services
75
76`grpc_cli ls` command lists services and methods exposed at a given port:
77
78- List all the services exposed at a given port
79
80  ```sh
81  $ ./grpc_cli ls localhost:50051
82  ```
83
84  output:
85  ```sh
86  grpc.examples.echo.Echo
87  grpc.reflection.v1alpha.ServerReflection
88  helloworld.Greeter
89  ```
90
91- List one service with details
92
93  `grpc_cli ls` command inspects a service given its full name (in the format of
94  \<package\>.\<service\>). It can print information with a long listing format
95  when `-l` flag is set. This flag can be used to get more details about a
96  service.
97
98  ```sh
99  $ ./grpc_cli ls localhost:50051 helloworld.Greeter -l
100  ```
101
102  output:
103  ```sh
104  filename: helloworld.proto
105  package: helloworld;
106  service Greeter {
107    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
108  }
109
110  ```
111
112### List methods
113
114- List one method with details
115
116  `grpc_cli ls` command also inspects a method given its full name (in the
117  format of \<package\>.\<service\>.\<method\>).
118
119  ```sh
120  $ ./grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l
121  ```
122
123  output:
124  ```sh
125    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
126  ```
127
128### Inspect message types
129
130We can use`grpc_cli type` command to inspect request/response types given the
131full name of the type (in the format of \<package\>.\<type\>).
132
133- Get information about the request type
134
135  ```sh
136  $ ./grpc_cli type localhost:50051 helloworld.HelloRequest
137  ```
138
139  output:
140  ```sh
141  message HelloRequest {
142    optional string name = 1[json_name = "name"];
143  }
144  ```
145
146### Call a remote method
147
148We can send RPCs to a server and get responses using `grpc_cli call` command.
149
150- Call a unary method
151
152  ```sh
153  $ ./grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'"
154  ```
155
156  output:
157  ```sh
158  message: "Hello gRPC CLI"
159  ```
160