twirp-ruby概要

はじめに

twirpというgRPCと似たようなRPCフレームワークを触っている中でのメモ。twirpはgRPCと似ていますがHTTP2に限定されずHTTP1.1でも使用できる便利なやつです。

基本

github.com

twirp-rubyはtwirpをRubyで動かすやつです

登場人物

  • Service...ProtocolBufferで定義されたService。その中身は実はRackアプリケーション

  • 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からの呼び出し方法

twitchtv/twirp-ruby

# 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連携

github.com