🐈‍⬛

gPRCのprotoでdate型やdecimal型を扱う

2023/08/11に公開

gRPCについて

基礎知識は知っている前提で話しますが、
grpcは以下のようにserviceとmethodに分けて、宣言しprotoファイルを作成していきます。

syntax = "proto3";
package myapp;

// サービスの定義
service GreetingService {
	rpc Hello (HelloRequest) returns (HelloResponse); 
}

// 型の定義
message HelloRequest {
	string name = 1;
}

message HelloResponse {
	string message = 1;
}

messageの型定義について

messageの型定義には、組み込みでstringboolenumなどが用意されている他に、Googleが定義してパッケージとして公開したWellKnownTypesというものがあり、日付はこちらのTimestamp型などを利用することが多いと思います。

組み込み型の仕様
https://protobuf.dev/programming-guides/proto3/
Well Known Types
https://protobuf.dev/reference/protobuf/google.protobuf/

import "google/protobuf/timestamp.proto";

message stores {
	bool is_open = 1;
	google.protobuf.Timestamp close_time = 2;
}

gPRCのprotoでdate型やdecimal型を扱う場合

上記の組み込みやWellKnownTypes定義されていないdate型やdecimal型等を扱う場合、以下のように時刻ごとにint32で分離して保持するようなmessageを自前で型定義を作成して、設定する必要があります。decimalは計算時に誤差が出るdoubleなどでは大体できないので、stringで保持する必要があります。

message tax {
  Date start_date = 1;
  Decimal rate = 1;
}

message Date {
  int32 year = 1;
  int32 month = 2;
  int32 day = 3;
}

message Decimal {
  string value = 1;
}

ただこれを自前で考えて作成していると、skeemaの定義の方針としてあっているか定かではないし、別の型が出るたびに毎回考えて作成しないといけません。

上記のような場合はgoogleapisで作成されているオリジナルのインターフェースを確認して、参照もしくはimportしてそのまま利用することで解消することができます。

googleapisについて

READMEを確認してみると以下のようなことが書いてあります。
https://github.com/googleapis/googleapis/blob/master/README.md

翻訳アプリによると、googleで利用されてているRESTとgRPCのオリジナルのインターフェースがあるので、定義にすることで理解が深まりますよってことみたいです。

ではgoogleapisgRPCのインターフェースのREADMEを確認してみると以下のようなことが書いてありました。

https://github.com/googleapis/googleapis/blob/master/google/type/README.md

翻訳アプリによると、Google APIの共通型の定義が含まれます。JavaやC#のような主要なプログラミング言語に匹敵する設計品質を持ってくださいと書いてありました。

それだけ設計品質が高いのであれば、参考ではなくそのままimportして使っていいのでは?と考えたので、importして利用して設定するようにしてみました。

import "google/type/date.proto";

message tax {
  google.type.Date start_date = 1;
  google.type.Decimal rate = 1;
}

これでわざわざ自前でもたなくて済みますし、googleが定義済みのものに乗っかれてとてもスッキリしました。
他にもmoneyや緯度軽度のlatlngなど便利なものがあるので、確認して活用していきたいです!

Discussion