twirp-ruby概要
はじめに
twirpというgRPCと似たようなRPCフレームワークを触っている中でのメモ。twirpはgRPCと似ていますがHTTP2に限定されずHTTP1.1でも使用できる便利なやつです。
基本
登場人物
Service
...ProtocolBufferで定義されたService。その中身は実はRackアプリケーション- 合わせて読もうRackとは何か - Qiita
Handler
...Serviceがどう動くかを定義Client
...Service呼ぶやつ
ServiceはServiceをRackアプリケーショとして定義するが、どう動くかについては定義していない。Handlerを差しこむことで中身の動きを定義する 例:
HogeService.new(FugaHandler)
ちなみに以下のような形でHookポイントがあるので、各Hookポイントで処理を書くことが可能
routing -> before -> handler -> on_success -> on_error
具体的なService, Handler, Clientのコードは以下となる
module Example class HelloWorldService < Twirp::Service package "example" service "HelloWorld" rpc :Hello, HelloRequest, HelloResponse, :ruby_method => :hello end class HelloWorldClient < Twirp::Client client_for HelloWorldService end end class HelloWorldHandler def hello(req, env) if req.name.empty? return Twirp::Error.invalid_argument("name is mandatory") end {message: "Hello #{req.name}"} end end
Service内で使用しているメソッド詳細
package
... Serviceのパッケージ名を定義。まじでパッケージ名的なことにしか使われないservice
...Serviceのサービス名を定義。まじでサービス名的なことにしか使われないrpc
...Twirp::Service
にはrpcsというrpcの定義をためる変数がある。そこにrpcを追加する
rpcsには以下のようなデータが追加される
twirp-ruby/service_dsl.rb at 3ec36d2653a14eb8cc73409fb20889e8484db371 · twitchtv/twirp-ruby · GitHub
rpcdef = { rpc_method: rpc_method.to_sym, # as defined in the Proto file. input_class: input_class, # google/protobuf Message class to serialize the input (proto request). output_class: output_class, # google/protobuf Message class to serialize the output (proto response). ruby_method: opts[:ruby_method].to_sym, # method on the handler or client to handle this rpc requests. } @rpcs ||= {} @rpcs[rpc_method.to_s] = rpcdef
Clientからの呼び出し方法
# Equivalent RPC calls client.rpc(:Hello, HelloRequest.new(name: "World")) # generic rpc method client.hello(HelloRequest.new(name: "World")) # DSL method with message object client.hello(name: "World") # DSL method with message attributes
gRPCと違い、Requestクラスを使わずともHashで呼べる
Client呼び出し時の戻り値
The response is a Twirp::ClientResponse object with the properties data (success) and error (failure).
しかも、errorは Twirp::Error
が返される。gRPCと違い直接ProtocolBufferで定義したmessageを返さないので注意。
Rails連携
Twirp::Rails.services
にservice一覧を保持bindメソッド
をHandler中に記載することでHandlerをServiceに紐づけて上記service一覧に追加config/routes.rb
内にuse_twirp
と書くことによりserviceのrpcメソッドに対応したルーティングを生成する- twirp-rails/routes.rb at e07923de2b1cdc371b157d82765735a3ba2d3fe0 · nikushi/twirp-rails · GitHub
- Railsはrackアプリケーションにルーティングすることができるので、この機能を用いる(Rails のルーティング - Rails ガイド)