Write down the procedure for implementing the gRPC client in Ruby as a reminder.
--Install grpc
gem to use gRPC with Ruby
--By including this, you will be able to use the classes required for implementing the client.
gem 'grpc', '~> X.XX.X'
--There are several ways to manage .proto files, but see this article for details.
--Use a Gem called grpc_tools
to compile .proto into an rb file
$ gem install grpc-tools
--The compile command looks like the following
$ grpc_tools_ruby_protoc -I ./proto \--ruby_out=lib --grpc_out=lib ./proto/hoge_proto/*.proto
--Specify a directory to search for .proto files with the -I
option
--Specify the output destination directory after compilation with the --ruby_out
option
――It's fine anywhere, but it seems that there are many / lib
--In the first argument of the --grpc_out
option, specify the output destination of the class file that will be the stub after compilation, and in the second argument, specify the directory containing the .proto file to be compiled.
--If the compilation is successful, the pb.rb file corresponding to each proto and the hoge_services_pb.rb file that imports all of them and modularizes them are generated.
--This hoge_services_pb.rb has the definition of rpc method and the definition of Stub, and this class will be used for calling.
Now that the preparations are complete, we will actually implement it from here. First, create the stub instance needed to make the gRPC call. Regarding the creation of a stub instance, I often see the method of creating a file under / initializer and creating a new file there, but I didn't want to plunge into a global variable, so this time I cut the model class and apply the singleton pattern. Implemented in. To be honest, I'm still looking for best practices around here.
model/grpc/hoge_service_client.rb
require 'proto/hoge_services_pb'
require 'singleton'
#It is better to make this from the configuration file for each environment
END_POINT = "localhost:50051"
class Grpc::HogeServiceClient
include Singleton
attr_reader :stub
def initialize
@stub = HogeProto::HogeService::Stub.new(END_POINT, :this_channel_is_insecure)
end
end
--For the Stub instance creation part, as mentioned above, the instance is created by creating a new Stub described in hoge_services_pb.rb. --The first argument of new specifies the gRPC server endpoint --The second argument is an argument for encryption during rpc communication, and if you want to operate it properly, you will need to specify the SSL certificate path, etc.
Try to actually call rpc using the Stub created above
grpc/hoge.rb
class Grpc::Hoge
def get_name(params)
#Create an instance of model that has a Stub instance
client = Grpc::HogeServiceClient.instance
#Create request data required for rpc call
req = get_name_request(params)
#Create metadata if needed
meta = Hash.new
meta["x-app-id"] = "hogeghoge"
meta["x-app-password"] = "fugafuga"
begin
#Here rpc call
client.stub.get_name(req, {metadata: meta})
res = "success"
rescue GRPC::BadStatus => ex
res = "error"
rescue ex
res = "unexpected error"
end
res
end
private
def get_name_request(params)
HogeProto::GetNameRequest.new(
id: params[:id]
)
end
--You are calling rpc in the client.stub.get_name
part
--If the result of this call is an error (Status.Codes is not OK), an exception will occur, so enclose it in begin and rescue if it is an error.
--For meta
, the metadata is set at the time of gRPC call.
--Here, the ID and password are set, but it seems better to initialize the common necessary items as instance variables on the model side that creates the stub.
――It seems that you can set the value in Hash format normally.
--However, note that uppercase letters cannot be used for keys.
As I mentioned earlier, when an rpc call returns an error status response, an exception of GRPC :: BadStatus
class occurs.
Therefore, it is necessary to always begin ~ rescue.
Also, if the server side returns with error_details packed, it is necessary to implement to retrieve it.
Reference: https://www.rubydoc.info/gems/grpc/GRPC/BadStatus
Recommended Posts