迷ったらカレー

技術系の雑多なブログ

Node.jsでサクッとGRPCを使うためのライブラリgrpc-kitをつくりました

この記事は、Recruit Engineers Advent Calendar 2018 4日目の代打記事です。

こんにちは。リクルートでエンジニアをやっている加藤です。 アドベントカレンダーの穴が寂しかったので埋め記事投稿です。つい先日、dev.toに投稿した元記事の和訳版記事になります。村上春樹にでもなった気分です。

タイトルの通りこの記事では、Node.jsでGRPCを簡単に使うためのライブラリを作ったので、そのご紹介をしたいと思います。

github.com

GRPCのアプリケーションをNode.jsで作るときには、grpc@grpc/proto-loaderというライブラリを使います。 この子達を使うとサクッとGRPCのサーバ/クライアントを作ることができてとても有難いのですが、いかんせんAPIがプリミティブなので個人的に使いづらさを感じていました。もっとこう、createClientとかcreateServerとかでインスタンス作って、useみたいのでミドルウェアっぽく設定追加して、という感じで使いたい欲求がありました。

そんなわけで、grpc@grpc/proto-loaderをラップしたgrpc-kitというライブラリをつくりました。jsペライチ100行未満の超お手軽ライブラリです。以下のような感じで使います。

greeter.proto

syntax="proto3";

package greeter;

service Greeter {
  rpc Hello (RequestGreet) returns (ResponseGreet) {}
  rpc Goodbye (RequestGreet) returns (ResponseGreet) {}
}

message RequestGreet {
  string name = 1;
}

message ResponseGreet {
  string message = 1;
}

server.js

const {createServer} = require("grpc-kit");
const server = createServer();

server.use({
  protoPath: "/path/to/greeter.proto",
  packageName: "greeter",
  serviceName: "Greeter",
  routes: {
    hello: (call, callback) => {
      callback(null, { message: `Hello, ${call.request.name}` });
    },
    goodbye: async (call) => {
      return { message: `Goodbye, ${call.request.name}` };
    }
  }
});

server.listen("0.0.0.0:50051");

createServergrpc.Server をラップしたクラスのインスタンスを返します。このインスタンスuse メソッドを提供していて、greeter.protoへのパス、パッケージ名、サービス名、それからgreeter.protoで定義された各メソッド(hello, goodbye)のハンドラを渡すことができます。ハンドラには、asyncな子も、asyncじゃない子も渡せるようにしてあります。これで設定は完了なので、あとはlisten というお里が知れそうな名前のメソッドにアドレスを渡してサーバを起動します。

client.js

//client.js
const {createClient} = require("grpc-kit");
const client = createClient({
  protoPath: "/path/to/greeter.proto",
  packageName: "greeter",
  serviceName: "Greeter"
}, "0.0.0.0:50051");

client.hello({ name: "Jack" }, (err, response) => {
  if(err) throw err;
  console.log(response.message);
});

client.goodbye({ name: "John" }, (err, response) => {
  if(err) throw err;
  console.log(response.message);
});

createClientgrpc.Clientインスタンスをそのまま返します。これはもう処理をまとめて僕が好きな形にしただけです。

さらに詳しい使い方については、 リポジトリ のREADMEと、あとexampleにサンプルコードを入れてあるのでご参照ください。 この記事が何かのお役に立てば幸いです。