gRPC - Go Quick Startの和訳

この記事は2019/02/12時点の[Go Quick Start](https://grpc.io/docs/quickstart/go.html#before-you-begin)を和訳したものです。

---

このガイドでは、GoでgRPCを使い始めるための簡単な例を紹介します。

## はじめる前に

### 前提条件  

**Goのバージョン**

gRPCはGo 1.6以上が必要です。（[こちら](https://github.com/grpc/grpc-go/commit/59a2cfbdf9272f6334fe4856b6e7c8d212845b3d)によると1.9以上）

```
$ go version
```
Go自体のインストール手順については、このガイドに従ってください。: [Getting Started - The Go Programming Language](https://golang.org/doc/install)  

**gRPCのインストール**  
gRPCをインストールするには、次のコマンドを使用します。  

```
$ go get -u google.golang.org/grpc
```

**Protocol Buffers v3のインストール**
gRPCサービスコードを生成するために使用されるprotocコンパイラをインストールしてください。これを行う最も簡単な方法は、ここからあなたのプラットフォーム用のコンパイル済みバイナリ`（protoc-<version>-<platform>.zip）`をダウンロードすることです: https://github.com/google/protobuf/releases

- ダウンロードしたファイルを解凍してください
- protocバイナリファイルへのパスを含めるように環境変数PATHを更新します。

---

**個人的な補足**
protocのインストールは[MacならHomebrewでも可能](https://qiita.com/tkmn0/items/7208c880693e63ca247a)です。この時点で`protoc --version`で正しくprotocがインストールされたか確認しておくと良い。

---

次に、Go用のprotocプラグインをインストールします

```
$ go get -u github.com/golang/protobuf/protoc-gen-go
```

コンパイラプラグイン`protoc-gen-go`が`$GOBIN`にインストールされ、デフォルトで`$GOPATH/bin`になります。プロトコルコンパイラ（protoc）がプラグインを見つけるには、`$GOPATH/bin`が`$PATH`に入っている必要があります。

```
$ export PATH=$PATH:$GOPATH/bin
``` 

## サンプルのダウンロード  
`go get google.golang.org/grpc`で取得されたgrpcコードにも例が含まれています。それらはexamplesディレクトリの下にあります：`$GOPATH/src/google.golang.org/grpc/examples`

## サンプルのビルド

サンプルディレクトリに移動します。  

```
$ cd $GOPATH/src/google.golang.org/grpc/examples/helloworld
```

gRPCサービスは、対応する`.pb.go`ファイルを生成するために使用される`.proto`ファイルで定義されています。 `.pb.go`ファイルは、プロトコルコンパイラ（protoc）を使用して`.proto`ファイルをコンパイルすることによって生成されます。

```
.protoファイル -> protocでコンパイル -> .pb.goファイル
```  

この例の目的のために、`helloworld.pb.go`ファイルは（`helloworld.proto`をコンパイルすることによって）すでに生成されており、次のディレクトリにあります。`$GOPATH/src/google.golang.org/grpc/examples/helloworld/helloworld`


この`helloworld.pb.go`ファイルが次のものを含みます。

- 生成されたクライアントとサーバーのコード
- HelloRequestおよびHelloReplyメッセージタイプを生成、直列化、および取得するためのコード 

## 試してみよう！  

サーバーとクライアントのコードをコンパイルして実行するには、`go run`コマンドを使用できます。
examplesディレクトリ内で以下を実行時して、 

```
$ go run greeter_server/main.go
```

別の端末から以下を実行します。

```
$ go run greeter_client/main.go
```

If things go smoothly, you will see the Greeting: Hello world in the client side output.

上手くいけばクライアント側の出力で`Greeting: Hello world`が見られます。  

おめでとうございます。 gRPCを使ってクライアントサーバーアプリケーションを実行することができました :tada: 

## gRPCサービスの更新

それでは、クライアントが呼び出すためのサーバー上の追加メソッドを持つアプリケーションを更新する方法を見てみましょう。 当社のgRPCサービスはプロトコルバッファを使用して定義されています。 [What is gRPC?](https://qiita.com/tikidunpon/items/28690424aa09efe81597)と[gRPC Basics - Go](https://qiita.com/tikidunpon/items/5e8c7e167257b6fb7d00)`で.proto`ファイルでサービスを定義する方法についてもっと多くのことを見つけることができます。今のところ、サーバーとクライアントの「スタブ」の両方に、クライアントからHelloRequestパラメーターを受け取り、サーバーからHelloReplyを返すSayHello RPCメソッドがあり、このメソッドは次のように定義されています。

```proto
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
```

Greeterサービスに2つのメソッドがあるようにこれを更新しましょう。上記と同じ例のディレクトリ（`$GOPATH/src/google.golang.org/grpc/examples/helloworld`）にいることを確認してください。

`helloworld/helloworld.proto`を編集し、同じ`SayHelloAgain`メソッドで同じリクエストとレスポンスタイプを使用して更新します。

```proto
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // Sends another greeting
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
```

## gRPCコードの生成
次に、新しいサービス定義を使用するために、アプリケーションで使用されているgRPCコードを更新する必要があります。上記と同じ例のディレクトリから（`$GOPATH/src/google.golang.org/grpc/examples/helloworld`）

```sh

$ protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld 
```

これにより、新しい変更で`helloworld.pb.go`が再生成されます。

## アプリケーションの更新と実行  

これでサーバーとクライアントのコードが新しく生成されましたが、サンプルアプリケーションの人が書いた部分に新しいメソッドを実装して呼び出す必要があります。

**サーバーの更新**
`greeter_server/main.go`を編集して、それに以下の関数を追加します。

```go
func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
        return &pb.HelloReply{Message: "Hello again " + in.Name}, nil
}
```

**クライアントの更新**
`greeter_client/main.go`を編集して、main関数に次のコードを追加します。

```go
r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name})
if err != nil {
        log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)

```

**実行！**  

サーバーを実行します。

```sh

$ go run greeter_server/main.go
```

別の端末で、クライアントを実行します

```sh
$ go run greeter_client/main.go
```

更新された出力が表示されるはずです。

```sh
$ go run greeter_client/main.go
Greeting: Hello world
Greeting: Hello again world
```

## What’s next  

- gRPCがどのように機能するかの詳細な説明は[What is gRPC?](https://grpc.io/docs/guides/)と[gRPC Concepts](https://grpc.io/docs/guides/concepts.html)を読んでください。  
- [gRPC Basics：Go](https://qiita.com/tikidunpon/items/5e8c7e167257b6fb7d00)でより詳細なチュートリアルを進めてください。
- [リファレンスドキュメント](https://godoc.org/google.golang.org/grpc)でgRPC Go core 
 APIを調べてください。