Home | History | Annotate | Download | only in doc
      1 # gRPC Server Reflection Tutorial
      2 
      3 gRPC Server Reflection provides information about publicly-accessible gRPC
      4 services on a server, and assists clients at runtime to construct RPC
      5 requests and responses without precompiled service information. It is used by
      6 gRPC CLI, which can be used to introspect server protos and send/receive test
      7 RPCs.
      8 
      9 ## Enable Server Reflection
     10 
     11 ### Enable server reflection in C++ servers
     12 
     13 C++ Server Reflection is an add-on library, `libgrpc++_reflection`. To enable C++
     14 server reflection, you can link this library to your server binary.
     15 
     16 Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly
     17 contain symbols used by the application. On these platforms, LD flag
     18 `--no-as-needed` is needed for for dynamic linking and `--whole-archive` is
     19 needed for for static linking.
     20 
     21 This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates
     22 enabling c++ server reflection on Linux and MacOS.
     23 
     24 ## Test services using Server Reflection
     25 
     26 After enabling Server Reflection in a server application, you can use gRPC CLI
     27 to test its services.
     28 
     29 Instructions 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 
     32 Here we use `examples/cpp/helloworld` as an example to show the use of gRPC
     33 Server Reflection and gRPC CLI. First, we need to build gRPC CLI and setup an
     34 example 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 
    112 We can use`grpc_cli type` command to inspect request/response types given the
    113 full 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 
    130 We 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 
    145 Server Reflection can be used by clients to get information about gRPC services
    146 at runtime. We've provided a descriptor database called
    147 [grpc::ProtoReflectionDescriptorDatabase](../test/cpp/util/proto_reflection_descriptor_database.h)
    148 which implements the
    149 [google::protobuf::DescriptorDatabase](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor_database#DescriptorDatabase)
    150 interface. It manages the communication between clients and reflection services
    151 and the storage of received information. Clients can use it as using a local
    152 descriptor 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