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 for dynamic linking and `--whole-archive` is 19needed for 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