Merge pull request #937 from menghanl/reflection_tutorial

Add server-reflection-tutorial.md
diff --git a/Documentation/server-reflection-tutorial.md b/Documentation/server-reflection-tutorial.md
new file mode 100644
index 0000000..ca8e30c
--- /dev/null
+++ b/Documentation/server-reflection-tutorial.md
@@ -0,0 +1,152 @@
+# 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
+
+gRPC-go Server Reflection is implemented in package [reflection](https://github.com/grpc/grpc-go/tree/master/reflection). To enable server reflection, you need to import this package and register reflection service on your gRPC server.
+
+For example, to enable server reflection in `example/helloworld`, we need to make the following changes:
+
+```diff
+--- a/examples/helloworld/greeter_server/main.go
++++ b/examples/helloworld/greeter_server/main.go
+@@ -40,6 +40,7 @@ import (
+        "golang.org/x/net/context"
+        "google.golang.org/grpc"
+        pb "google.golang.org/grpc/examples/helloworld/helloworld"
++       "google.golang.org/grpc/reflection"
+ )
+
+ const (
+@@ -61,6 +62,8 @@ func main() {
+        }
+        s := grpc.NewServer()
+        pb.RegisterGreeterServer(s, &server{})
++       // Register reflection service on gRPC server.
++       reflection.Register(s)
+        if err := s.Serve(lis); err != nil {
+                log.Fatalf("failed to serve: %v", err)
+        }
+```
+
+We have made this change in `example/helloworld`, and we will use it as an example to show the use of gRPC server reflection and gRPC CLI in this tutorial.
+
+## gRPC CLI
+
+After enabling Server Reflection in a server application, you can use gRPC CLI to check its services.
+gRPC CLI is only available in c++. Instructions on how to use gRPC CLI can be found at [command_line_tool.md](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md).
+
+To build gRPC CLI:
+
+```sh
+git clone https://github.com/grpc/grpc
+cd grpc
+make grpc_cli
+cd bins/opt # grpc_cli is in directory bins/opt/
+```
+
+## Use gRPC CLI to check services
+
+First, start the helloworld server in grpc-go directory:
+
+```sh
+$ cd <grpc-go-directory>
+$ go run examples/helloworld/greeter_server/main.go
+```
+
+Open a new terminal and make sure you are in the directory where grpc_cli lives:
+
+```sh
+$ cd <grpc-cpp-dirctory>/bins/opt
+```
+
+### 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[json_name = "name"];
+  }
+  ```
+
+### 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"
+  ```
diff --git a/examples/helloworld/greeter_server/main.go b/examples/helloworld/greeter_server/main.go
index d572b22..162cf90 100644
--- a/examples/helloworld/greeter_server/main.go
+++ b/examples/helloworld/greeter_server/main.go
@@ -40,6 +40,7 @@
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	pb "google.golang.org/grpc/examples/helloworld/helloworld"
+	"google.golang.org/grpc/reflection"
 )
 
 const (
@@ -61,6 +62,8 @@
 	}
 	s := grpc.NewServer()
 	pb.RegisterGreeterServer(s, &server{})
+	// Register reflection service on gRPC server.
+	reflection.Register(s)
 	if err := s.Serve(lis); err != nil {
 		log.Fatalf("failed to serve: %v", err)
 	}