RubyでgRPC対応する
既存のRailsのRest APIをgRPC対応しました。
gem install
$ gem install grpc
$ gem install grpc-tools
protoファイル作成
api.proto
syntax = "proto3";
package api;
service LGTM {
rpc Items (ItemsRequest) returns (ItemsResponse) {}
rpc Upload (UploadRequest) returns (UploadResponse) {}
rpc Item (ItemRequest) returns (ItemResponse) {}
}
message Item {
int64 id = 1;
string url = 2;
}
message ItemsRequest {
int64 page = 1;
}
message ItemsResponse {
repeated Item items = 1;
}
message ItemRequest {
int64 id = 1;
}
message ItemResponse {
Item item = 1;
}
message UploadRequest {
string image = 1;
}
message UploadResponse {
string result = 1;
}
ファイル生成
$ grpc_tools_ruby_protoc -I . --ruby_out=lib --grpc_out=lib ./api.proto
$ tree lib
lib
├── api_pb.rb
├── api_services_pb.rb
Server側
grpc_api_server.rb
#!/usr/bin/env ruby
this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(this_dir, 'lib')
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
require 'grpc'
require 'api_services_pb'
require 'date'
require ::File.expand_path('../config/environment', __FILE__)
class APIServer < Api::LGTM::Service
def items(req, _unused_call)
res_items = Array.new()
items = Item.order("id desc").page(req.page)
for item in items do
res_item = Api::Item.new(id: item.id, url: item.url)
res_items.push(res_item)
end
Api::ItemsResponse.new(items: res_items)
end
def item(req, _unused_call)
item = Item.find(req.id)
res_item = Api::Item.new(id: item.id, url: item.url)
Api::ItemResponse.new(item: res_item)
end
end
def main
s = GRPC::RpcServer.new
s.add_http2_port('0.0.0.0:5555', :this_port_is_insecure)
s.handle(APIServer)
s.run_till_terminated
end
main
Client側
#!/usr/bin/env ruby
this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(this_dir, 'lib')
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
require 'grpc'
require 'api_services_pb'
def main
stub = Api::LGTM::Stub.new('localhsot:5555', :this_channel_is_insecure)
items = stub.items(Api::ItemsRequest.new(page: 1)).items
p "#{items}"
item = stub.item(Api::ItemRequest.new(id: 1)).item
p "#{item.url}"
end
main
テスト
$ ruby grpc_api_server.rb
$ ruby grpc_api_client.rb