概要
あまりユースケースはないかもしれませんが、gRPCのリクエストやレスポンスでプリミティブ型を使いたい場合、どうすればいいんだろうとふと気になりました。少し調べてみた内容をメモ書きしたいと思います。
調べた結果
Can protobuf service method return primitive type?のstackoverflowの記事にある通り、基本的にgRPCでプリミティブ型をそのまま返すことはできず、何かしらのmessageで包む必要があります。ただ、この記事の回答にあるwrappers.proto
を使用すれば、プリミティブ型をmessage型でラップされてるものが用意されているので、プリミティブ型っぽい感じで定義することはできそうです。
また、golangではラップされている型がwrapperspbが用意されていて、コード出力後はこの型を使用すれば良さそうです。
実装サンプル
せっかくなので、wrappersを使用した実装サンプルのprotoとgolangでの実装を記載します。
なお、goの実装でconnect-goを使用していますが、使用する必要は特にありません。
sample.proto
syntax = "proto3";
option go_package = "sample/src/gen/proto;placeNote";
import "google/protobuf/wrappers.proto";
package placeNote;
service SampleService {
rpc GetBoolFromString(google.protobuf.StringValue) returns (google.protobuf.BoolValue) {}
}
sample.go
package server
import (
"context"
"github.com/bufbuild/connect-go"
"google.golang.org/protobuf/types/known/wrapperspb"
)
type SampleServer struct{}
func (s *SampleServer) GetBoolFromString(
ctx context.Context,
req *connect.Request[wrapperspb.StringValue],
) (*connect.Response[wrapperspb.BoolValue], error) {
// リクエストから文字列を取得
_, err := sampleFunction(req.Msg.Value) // 関数の処理内容は記載割愛
if err != nil {
return nil, err
}
return connect.NewResponse(&wrapperspb.BoolValue{Value: true}), nil
}