Edited at

gRPCって何?

この記事は、gRPC を調べたことを走り書きしたレベルものです。実際の利用経験に基づいた情報でもなければ、しっかり時間をかけて裏付けをとった情報でもないため、誤った理解が含まれている可能性がある点にご注意ください。ツッコミや編集リクエストは歓迎します。


概要

gRPC は、RPC (Remote Procedure Call) を実現するためにGoogleが開発したプロトコルの1つです。Protocol Buffers を使ってデータをシリアライズし、高速な通信を実現できる点が特長です。

gRPCでは、IDL(インターフェース定義言語)を使ってあらかじめAPI仕様を .proto ファイルとして定義し、そこからサーバー側&クライアント側に必要なソースコードのひな形を生成します。言語に依存しないIDLで先にインタフェースを定義することで、様々なプログラミング言語の実装を生成できるというメリットがあります。

image.png

What is gRPC?より抜粋


開発の流れ

実際に gRPC を使って開発する流れは次のようになります。



  1. .proto ファイルの作成


    helloworld.proto

    // HelloRequest を受け取って HelloReply を返すメソッドの定義
    
    service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
    }

    // HelloRequest のリクエスト定義
    message HelloRequest {
    string name = 1;
    }

    // HelloReply のレスポンス定義
    message HelloReply {
    string message = 1;
    }





  2. .proto をコンパイルして、サーバー&クライアントのひな形コード生成


    helloworld.pb.go

    // Code generated by protoc-gen-go. DO NOT EDIT.
    
    // source: helloworld.proto
    ...
    package helloworld
    ...
    // The request message containing the user's name.
    type HelloRequest struct {
    Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
    }

    func (m *HelloRequest) Reset() { *m = HelloRequest{} }
    func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
    func (*HelloRequest) ProtoMessage() {}
    func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

    func (m *HelloRequest) GetName() string {
    if m != nil {
    return m.Name
    }
    return ""
    }
    ...




  3. 2.を使ってサーバー&クライアントを実装する



実装

様々な言語がサポートされており、IDLの価値を高めている気がします。


メリット?


  • JSON-RPC と同様に、REST APIよりはURL設計が楽そう


  • .proto ファイルにAPI仕様を強制的に明文化できる

  • REST APIやJSON-RPCとは違ってパラメーターをきちんと型付けした状態で扱える安心感


    • GoやJavaなどの静的型付け言語と相性がよさそう



  • ボイラープレートコードを自動生成でき、品質も上がりそう


    • 自動生成が逆に扱いづらいというケースがあるのか現時点では不明



  • HTTP/2を活かした高速な双方向ストリーミング通信が可能


デメリット?


  • REST APIほどは周辺のエコシステム(デバッグツールやAPIドキュメント生成など)が揃っていなさそう

  • データがシリアライズされるのでデバッグはやりづらそう

  • バックサーバー間通信には使えるが、フロントエンド/バックエンドサーバー間通信には使えない



    • grpc-gateway を使うとREST APIを受け付けるリバースプロキシサーバーを立てられるみたい



  • JSON-RPCなどと比べて学習コストは大きそう


追記(2019/01/31)

gRPC-Webリリース でフロントエンド/バックエンド間での通信にもgRPCが使えるようになりましたが、バックエンドのgRPCサーバーと直接通信できるわけではなく、Envoy のようなgRPC Web対応のプロキシをバックエンド側に立てて通信するようです。



調査できていない


  • APIドキュメント系のツール

  • テスト、デバッグ周りのツール


  • grpc-ecosystem の下に色々ありそう


参考情報