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
5requests and responses without precompiled service information. It is used by
6gRPC CLI, which can be used to introspect server protos and send/receive test
7RPCs.
8
9## Enable Server Reflection
10
11### Enable server reflection in C++ servers
12
13C++ Server Reflection is an add-on library, `libgrpc++_reflection`. To enable C++
14server reflection, you can link this library to your server binary.
15
16Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly
17contain symbols used by the application. On these platforms, LD flag
18`--no-as-needed` is needed for dynamic linking and `--whole-archive` is
19needed for static linking.
20
21This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates
22enabling c++ server reflection on Linux and MacOS.
23
24## Test services using Server Reflection
25
26After enabling Server Reflection in a server application, you can use gRPC CLI
27to test its services.
28
29Instructions on how to use gRPC CLI can be found at
30[command_line_tool.md](command_line_tool.md), or using `grpc_cli help` command.
31
32Here we use `examples/cpp/helloworld` as an example to show the use of gRPC
33Server Reflection and gRPC CLI. First, we need to build gRPC CLI and setup an
34example server with Server Reflection enabled.
35
36- Setup an example server
37
38  Server Reflection has already been enabled in the
39  [Makefile](../examples/cpp/helloworld/Makefile) of the helloworld example. We
40  can simply make it and run the greeter_server.
41
42  ```sh
43  $ make -C examples/cpp/helloworld
44  $ examples/cpp/helloworld/greeter_server &
45  ```
46
47- Build gRPC CLI
48
49  ```sh
50  make grpc_cli
51  cd bins/opt
52  ```
53
54  gRPC CLI binary `grpc_cli` can be found at `bins/opt/` folder. This tool is
55  still new and does not have a `make install` target yet.
56
57### List services
58
59`grpc_cli ls` command lists services and methods exposed at a given port
60
61- List all the services exposed at a given port
62
63  ```sh
64  $ grpc_cli ls localhost:50051
65  ```
66
67  output:
68  ```sh
69  helloworld.Greeter
70  grpc.reflection.v1alpha.ServerReflection
71  ```
72
73- List one service with details
74
75  `grpc_cli ls` command inspects a service given its full name (in the format of
76  \<package\>.\<service\>). It can print information with a long listing format
77  when `-l` flag is set. This flag can be used to get more details about a
78  service.
79
80  ```sh
81  $ grpc_cli ls localhost:50051 helloworld.Greeter -l
82  ```
83
84  output:
85  ```sh
86  filename: helloworld.proto
87  package: helloworld;
88  service Greeter {
89    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
90  }
91
92  ```
93
94### List methods
95
96- List one method with details
97
98  `grpc_cli ls` command also inspects a method given its full name (in the
99  format of \<package\>.\<service\>.\<method\>).
100
101  ```sh
102  $ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l
103  ```
104
105  output:
106  ```sh
107    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
108  ```
109
110### Inspect message types
111
112We can use`grpc_cli type` command to inspect request/response types given the
113full name of the type (in the format of \<package\>.\<type\>).
114
115- Get information about the request type
116
117  ```sh
118  $ grpc_cli type localhost:50051 helloworld.HelloRequest
119  ```
120
121  output:
122  ```sh
123  message HelloRequest {
124    optional string name = 1;
125  }
126  ```
127
128### Call a remote method
129
130We can send RPCs to a server and get responses using `grpc_cli call` command.
131
132- Call a unary method
133
134  ```sh
135  $ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'"
136  ```
137
138  output:
139  ```sh
140  message: "Hello gRPC CLI"
141  ```
142
143## Use Server Reflection in a C++ client
144
145Server Reflection can be used by clients to get information about gRPC services
146at runtime. We've provided a descriptor database called
147[grpc::ProtoReflectionDescriptorDatabase](../test/cpp/util/proto_reflection_descriptor_database.h)
148which implements the
149[google::protobuf::DescriptorDatabase](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor_database#DescriptorDatabase)
150interface. It manages the communication between clients and reflection services
151and the storage of received information. Clients can use it as using a local
152descriptor database.
153
154- To use Server Reflection with grpc::ProtoReflectionDescriptorDatabase, first
155  initialize an instance with a grpc::Channel.
156
157  ```c++
158  std::shared_ptr<grpc::Channel> channel =
159      grpc::CreateChannel(server_address, server_cred);
160  grpc::ProtoReflectionDescriptorDatabase reflection_db(channel);
161  ```
162
163- Then use this instance to feed a
164  [google::protobuf::DescriptorPool](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor#DescriptorPool).
165
166  ```c++
167  google::protobuf::DescriptorPool desc_pool(&reflection_db);
168  ```
169
170- Example usage of this descriptor pool
171
172  * Get Service/method descriptors.
173
174    ```c++
175    const google::protobuf::ServiceDescriptor* service_desc =
176        desc_pool->FindServiceByName("helloworld.Greeter");
177    const google::protobuf::MethodDescriptor* method_desc =
178        desc_pool->FindMethodByName("helloworld.Greeter.SayHello");
179    ```
180
181  * Get message type descriptors.
182
183    ```c++
184    const google::protobuf::Descriptor* request_desc =
185        desc_pool->FindMessageTypeByName("helloworld.HelloRequest");
186    ```
187
188  * Feed [google::protobuf::DynamicMessageFactory](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.dynamic_message#DynamicMessageFactory).
189
190    ```c++
191    google::protobuf::DynamicMessageFactory(&desc_pool);
192    ```
193