# 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
gRPC CLI, which can be used to introspect server protos and send/receive test
RPCs.

## Enable Server Reflection

### Enable server reflection in C++ servers

C++ Server Reflection is an add-on library, `libgrpc++_reflection`. To enable C++
server reflection, you can link this library to your server binary.

Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly
contain symbols used by the application. On these platforms, LD flag
`--no-as-needed` is needed for dynamic linking and `--whole-archive` is
needed for static linking.

This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates
enabling c++ server reflection on Linux and MacOS.

## Test services using Server Reflection

After enabling Server Reflection in a server application, you can use gRPC CLI
to test its services.

Instructions on how to use gRPC CLI can be found at
[command_line_tool.md](command_line_tool.md), or using `grpc_cli help` command.

Here we use `examples/cpp/helloworld` as an example to show the use of gRPC
Server Reflection and gRPC CLI. First, we need to build gRPC CLI and setup an
example server with Server Reflection enabled.

- Setup an example server

  Server Reflection has already been enabled in the
  [Makefile](../examples/cpp/helloworld/Makefile) of the helloworld example. We
  can simply make it and run the greeter_server.

  ```sh
  $ make -C examples/cpp/helloworld
  $ examples/cpp/helloworld/greeter_server &
  ```

- Build gRPC CLI

  ```sh
  make grpc_cli
  cd bins/opt
  ```

  gRPC CLI binary `grpc_cli` can be found at `bins/opt/` folder. This tool is
  still new and does not have a `make install` target yet.

### List services

`grpc_cli ls` command lists services and methods exposed at a given port

- List all the services exposed at a given port

  ```sh
  $ grpc_cli ls localhost:50051
  ```

  output:
  ```sh
  helloworld.Greeter
  grpc.reflection.v1alpha.ServerReflection
  ```

- List one service with details

  `grpc_cli ls` command inspects a service given its full name (in the format of
  \<package\>.\<service\>). It can print information with a long listing format
  when `-l` flag is set. This flag can be used to get more details about a
  service.

  ```sh
  $ grpc_cli ls localhost:50051 helloworld.Greeter -l
  ```

  output:
  ```sh
  filename: helloworld.proto
  package: helloworld;
  service Greeter {
    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
  }

  ```

### List methods

- List one method with details

  `grpc_cli ls` command also inspects a method given its full name (in the
  format of \<package\>.\<service\>.\<method\>).

  ```sh
  $ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l
  ```

  output:
  ```sh
    rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {}
  ```

### Inspect message types

We can use`grpc_cli type` 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
  $ grpc_cli type localhost:50051 helloworld.HelloRequest
  ```

  output:
  ```sh
  message HelloRequest {
    optional string name = 1;
  }
  ```

### Call a remote method

We can send RPCs to a server and get responses using `grpc_cli call` command.

- Call a unary method

  ```sh
  $ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'"
  ```

  output:
  ```sh
  message: "Hello gRPC CLI"
  ```

## Use Server Reflection in a C++ client

Server Reflection can be used by clients to get information about gRPC services
at runtime. We've provided a descriptor database called
[grpc::ProtoReflectionDescriptorDatabase](../test/cpp/util/proto_reflection_descriptor_database.h)
which implements the
[google::protobuf::DescriptorDatabase](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor_database#DescriptorDatabase)
interface. It manages the communication between clients and reflection services
and the storage of received information. Clients can use it as using a local
descriptor database.

- To use Server Reflection with grpc::ProtoReflectionDescriptorDatabase, first
  initialize an instance with a grpc::Channel.

  ```c++
  std::shared_ptr<grpc::Channel> channel =
      grpc::CreateChannel(server_address, server_cred);
  grpc::ProtoReflectionDescriptorDatabase reflection_db(channel);
  ```

- Then use this instance to feed a
  [google::protobuf::DescriptorPool](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor#DescriptorPool).

  ```c++
  google::protobuf::DescriptorPool desc_pool(&reflection_db);
  ```

- Example usage of this descriptor pool

  * Get Service/method descriptors.

    ```c++
    const google::protobuf::ServiceDescriptor* service_desc =
        desc_pool->FindServiceByName("helloworld.Greeter");
    const google::protobuf::MethodDescriptor* method_desc =
        desc_pool->FindMethodByName("helloworld.Greeter.SayHello");
    ```

  * Get message type descriptors and create messages dynamically.

    ```c++
    const google::protobuf::Descriptor* request_desc =
        desc_pool->FindMessageTypeByName("helloworld.HelloRequest");
    google::protobuf::DynamicMessageFactory dmf;
    google::protobuf::Message* request = dmf.GetPrototype(request_desc)->New();
    ```

## Use Server Reflection in a Python client

See [Python Server Reflection](python/server_reflection.md).

