protovalidate 逆引きリファレンス(proto3)
今回は、protovalidate を使って Proto を定義する中で、毎回公式ドキュメントを確認するのが手間だと感じていました。
そこで、逆引き形式でサッと確認できるリファレンスがあれば便利だなと思い、この記事を作成してみました😊!
はじめに
protovalidate とは?
protovalidate は、Protocol Buffers に対するバリデーションルールを定義できる仕組みで、
Buf が提供する buf.validate 拡張に基づいています。
protobuf ファイルに制約(例:必須、最小値、最大長など)を直接書くことができます。
Protobufで唯一広く使用されている検証ライブラリであるprotoc-gen-validateの次世代版です。
こんな人におすすめ
- Protobuf や gRPC を使っているが、バリデーションの記述に迷っている方
- API の入力チェックをコードレスで共通化したい方
protoの定義時に、型安全に定義可能になります ⭐️
AnyRules
許可された型のいずれかである必要があるとき
The value
field must have a type_url
equal to one of the specified values.
google.protobuf.Any value = 1 [(buf.validate.field).any.in = ["type.googleapis.com/MyType1", "type.googleapis.com/MyType2"]];
禁止された型のいずれかでない必要があるとき
The field value
must not have a type_url
equal to any of the specified values.generated.
google.protobuf.Any value = 1 [(buf.validate.field).any.not_in = ["type.googleapis.com/ForbiddenType1", "type.googleapis.com/ForbiddenType2"]];
BoolRules
真偽値がtrueに限定されるとき
value must equal true
bool value = 1 [(buf.validate.field).bool.const = true];
真偽値がfalseに限定されるとき
value must equal false
bool value = 1 [(buf.validate.field).bool.const = false];
BytesRules
固定のバイト列だけを許可したいとき
value must be "\x01\x02\x03\x04"
bytes value = 1 [(buf.validate.field).bytes.const = "\x01\x02\x03\x04"];
バイト列の長さを指定のバイト数に制限したいとき
value length must be 4 bytes.
optional bytes value = 1 [(buf.validate.field).bytes.len = 4];
バイト列の最小長さを制限したいとき
value length must be at least 2 bytes.
optional bytes value = 1 [(buf.validate.field).bytes.min_len = 2];
バイト列の最大長さを制限したいとき
value must be at most 6 bytes.
optional bytes value = 1 [(buf.validate.field).bytes.max_len = 6];
正規表現でバイト列を制限したいとき
value must match regex pattern
optional bytes value = 1 [(buf.validate.field).bytes.pattern = "^[a-zA-Z0-9]+$"];
特定のバイト列で始まることを確認したいとき
value must start with the byte prefix "\x01\x02"
optional bytes value = 1 [(buf.validate.field).bytes.prefix = "\x01\x02"];
特定のバイト列で終わることを確認したいとき
value must end with the byte suffix "\x03\x04"
optional bytes value = 1 [(buf.validate.field).bytes.suffix = "\x03\x04"];
特定のバイト列を含む必要があるとき
value must contain the byte sequence \x02\x03
optional bytes value = 1 [(buf.validate.field).bytes.contains = "\x02\x03"];
許可されたバイト列のいずれかに一致させたいとき
value must in ["\x01\x02", "\x02\x03", "\x03\x04"]
optional bytes value = 1 [(buf.validate.field).bytes.in = {"\x01\x02", "\x02\x03", "\x03\x04"}];
禁止されたバイト列のいずれかに一致しないようにしたいとき
value must not in ["\x01\x02", "\x02\x03", "\x03\x04"]
optional bytes value = 1 [(buf.validate.field).bytes.not_in = {"\x01\x02", "\x02\x03", "\x03\x04"}];
IPv4 または IPv6 の形式であることを検証したいとき
value must be a valid IP address
optional bytes value = 1 [(buf.validate.field).bytes.ip = true];
IPv4 の形式であることを検証したいとき
value must be a valid IPv4 address
optional bytes value = 1 [(buf.validate.field).bytes.ipv4 = true];
IPv6 の形式であることを検証したいとき
value must be a valid IPv6 address
optional bytes value = 1 [(buf.validate.field).bytes.ipv6 = true];
DoubleRules
特定の値と完全に一致させたいとき
value must equal 42.0
double value = 1 [(buf.validate.field).double.const = 42.0];
特定の値より小さい値に制限したいとき
value must be less than 10.0
double value = 1 [(buf.validate.field).double.lt = 10.0];
特定の値以下に制限したいとき
value must be less than or equal to 10.0
double value = 1 [(buf.validate.field).double.lte = 10.0];
特定の値より大きい値に制限したいとき
value must be greater than 5.0 [double.gt]
double value = 1 [(buf.validate.field).double.gt = 5.0];
特定の値以上に制限したいとき
value must be greater than or equal to 5.0 [double.gte]
double value = 1 [(buf.validate.field).double.gte = 5.0];
特定の範囲内の値に制限したいとき
value must be greater than 5.0 and less than 10.0 [double.gt_lt]
double value = 1 [(buf.validate.field).double = { gt: 5.0, lt: 10.0 }];
許可された値のいずれかに一致させたいとき
value must be in list [1.0, 2.0, 3.0]
double value = 1 [(buf.validate.field).double = { in: [1.0, 2.0, 3.0] }];
禁止された値のいずれかに一致しないようにしたいとき
value must not be in list [1.0, 2.0, 3.0]
double value = 1 [(buf.validate.field).double = { not_in: [1.0, 2.0, 3.0] }];
無限大や NaN を許可せず、有限値に制限したいとき
value must be a finite number (not NaN or Infinity) [double.finite]
double value = 1 [(buf.validate.field).double.finite = true];
DurationRules
指定された秒数と完全に一致させたいとき
value must equal 5s
google.protobuf.Duration value = 1 [(buf.validate.field).duration.const = "5s"];
指定された秒数より短い値に制限したいとき
value must be less than 5s
google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = "5s"];
指定された秒数以下の値に制限したいとき
value must be less than or equal to 10s
google.protobuf.Duration value = 1 [(buf.validate.field).duration.lte = "10s"];
指定された秒数より長い値に制限したいとき
duration must be greater than 5s [duration.gt]
google.protobuf.Duration value = 1 [(buf.validate.field).duration.gt = { seconds: 5 }];
指定された秒数以上の値に制限したいとき
duration must be greater than or equal to 5s [duration.gte]
google.protobuf.Duration value = 1 [(buf.validate.field).duration.gte = { seconds: 5 }];
指定された時間の範囲内に制限したいとき
duration must be greater than or equal to 5s and less than 10s [duration.gte_lt]
google.protobuf.Duration value = 1 [(buf.validate.field).duration = { gte: { seconds: 5 }, lt: { seconds: 10 } }];
許可された複数の時間のいずれかに一致させたいとき
value must be in list [1s, 2s, 3s]
google.protobuf.Duration value = 1 [(buf.validate.field).duration.in = ["1s", "2s", "3s"]];
禁止された複数の時間のいずれかに一致しないようにしたいとき
value must not be in list [1s, 2s, 3s]
google.protobuf.Duration value = 1 [(buf.validate.field).duration.not_in = ["1s", "2s", "3s"]];
EnumRules
enum MyEnum {
MY_ENUM_UNSPECIFIED = 0;
MY_ENUM_VALUE1 = 1;
MY_ENUM_VALUE2 = 2;
}
特定の値だけを許可したいとき
The field value
must be exactly MY_ENUM_VALUE1.
MyEnum value = 1 [(buf.validate.field).enum.const = 1];
Enum に定義された値のみを許可したいとき(未定義の数値はエラー)
The field value
must be a defined value of MyEnum.
ExEnum value = 1 [(buf.validate.field).enum.defined_only = true];
指定した Enum 値のいずれかに一致させたいとき
The field value
must be equal to one of the specified values.
MyEnum value = 1 [(buf.validate.field).enum = { in: [1, 2]}];
指定した Enum 値のいずれかを除外したいとき
The field value
must not be equal to any of the specified values.
MyEnum value = 1 [(buf.validate.field).enum = { not_in: [1, 2]}];
Int32Rules
特定の値である必要があるとき
value must equal 42
int32 value = 1 [(buf.validate.field).int32.const = 42];
特定の値より小さい値に制限したいとき
value must be less than 10
int32 value = 1 [(buf.validate.field).int32.lt = 10];
特定の値以下に制限したいとき(その値も含む)
value must be less than or equal to 10
int32 value = 1 [(buf.validate.field).int32.lte = 10];
特定の値より大きい値に制限したいとき
value must be greater than 5 [int32.gt]
int32 value = 1 [(buf.validate.field).int32.gt = 5];
特定の値以上に制限したいとき(その値も含む)
value must be greater than or equal to 5 [int32.gte]
int32 value = 1 [(buf.validate.field).int32.gte = 5];
特定の範囲内の値に制限したいとき
value must be greater than 5 and less than 10 [int32.gt_lt]
int32 value = 1 [(buf.validate.field).int32 = { gt: 5, lt: 10 }];
許可された数値のいずれかに一致させたいとき
value must be in list [1, 2, 3]
int32 value = 1 [(buf.validate.field).int32 = { in: [1, 2, 3] }];
禁止された数値のいずれかに一致しないようにしたいとき
value must not be in list [1, 2, 3]
int32 value = 1 [(buf.validate.field).int32 = { not_in: [1, 2, 3] }];
MapRules
key-value ペアの最小数を指定したいとき
The field value
must have at least 2 key-value pairs.
map<string, string> value = 1 [(buf.validate.field).map.min_pairs = 2];
key-value ペアの最大数を指定したいとき
The field value
must have at most 3 key-value pairs.
map<string, string> value = 1 [(buf.validate.field).map.max_pairs = 3];
key の長さや文字数に制限をつけたいとき
The keys in the field value
must follow the specified constraints.
map<string, string> value = 1 [(buf.validate.field).map.keys = {
string: {
min_len: 3
max_len: 10
}
}];
value の長さや文字数に制限をつけたいとき
The values in the field value
must follow the specified constraints.
map<string, string> value = 1 [(buf.validate.field).map.values = {
string: {
min_len: 5
max_len: 20
}
}];
RepeatedRules
リストの最小要素数を指定したいとき
value must contain at least 2 items
repeated string value = 1 [(buf.validate.field).repeated.min_items = 2];
リストの最大要素数を指定したいとき
value must contain no more than 3 item(s)
repeated string value = 1 [(buf.validate.field).repeated.max_items = 3];
リスト内の要素をすべてユニークにしたいとき
repeated value must contain unique items
repeated string value = 1 [(buf.validate.field).repeated.unique = true];
リスト内の各要素に対して特定の制約(長さなど)を与えたいとき
The items in the field value
must follow the specified constraints.
repeated string value = 1 [(buf.validate.field).repeated.items = {
string: {
min_len: 3
max_len: 10
}
}];
StringRules
特定の文字列のみ許可したいとき
value must equal hello
string value = 1 [(buf.validate.field).string.const = "ok"];
文字数を正確に指定したいとき
value length must be exactly 5 characters
string value = 1 [(buf.validate.field).string.len = 5];
最小の文字数を指定したいとき
value length must be at least 3 characters
string value = 1 [(buf.validate.field).string.min_len = 3];
最大の文字数を指定したいとき
value length must be at most 10 characters
string value = 1 [(buf.validate.field).string.max_len = 10];
バイト数で正確に指定したいとき
value length must be exactly 6 bytes
string value = 1 [(buf.validate.field).string.len_bytes = 6];
最小バイト数を指定したいとき
value length must be at least 4 bytes
string value = 1 [(buf.validate.field).string.min_bytes = 4];
最大バイト数を指定したいとき
value length must be at most 8 bytes
string value = 1 [(buf.validate.field).string.max_bytes = 8];
正規表現パターンに一致させたいとき
value must match regex pattern
string value = 1 [(buf.validate.field).string.pattern = "^[a-zA-Z]+$"];
指定の接頭辞(prefix)で始まる必要があるとき
value must start with pre
string value = 1 [(buf.validate.field).string.prefix = "pre"];
指定の接尾辞(suffix)で終わる必要があるとき
value must end with post
string value = 1 [(buf.validate.field).string.suffix = "post"];
指定の文字列を含んでいる必要があるとき
value must contain substring inside
string value = 1 [(buf.validate.field).string.contains = "inside"];
指定の文字列を含んではいけないとき
value must not contain substring inside
string value = 1 [(buf.validate.field).string.not_contains = "inside"];
許可リスト内の文字列のみ許可したいとき
value must be in list ["apple", "banana"]
string value = 1 [
(buf.validate.field).string.in = "apple",
(buf.validate.field).string.in = "banana"
];
禁止リストに含まれる文字列はNGにしたいとき
value must not be in list ["orange", "grape"]
string value = 1 [
(buf.validate.field).string.not_in = "orange",
(buf.validate.field).string.not_in = "grape"
];
メールアドレスの形式にしたいとき
value must be a valid email address
string value = 1 [(buf.validate.field).string.email = true];
ホスト名の形式にしたいとき
value must be a valid hostname
string value = 1 [(buf.validate.field).string.hostname = true];
IPアドレス(IPv4 または IPv6)の形式にしたいとき
value must be a valid IP address
string value = 1 [(buf.validate.field).string.ip = true];
IPv4アドレスの形式にしたいとき
value must be a valid IPv4 address
string value = 1 [(buf.validate.field).string.ipv4 = true];
IPv6形式のみ許容したいとき
value must be a valid IPv6 address
string value = 1 [(buf.validate.field).string.ipv6 = true];
URI形式を確認したいとき
value must be a valid URI
string value = 1 [(buf.validate.field).string.uri = true];
URI参照の形式を確認したいとき
value must be a valid URI Reference
string value = 1 [(buf.validate.field).string.uri_ref = true];
ホスト名またはIPアドレスのどちらかである必要があるとき
value must be a valid hostname or IP address
string value = 1 [(buf.validate.field).string.address = true];
UUID(標準形式)の形式にしたいとき
value must be a valid UUID
string value = 1 [(buf.validate.field).string.uuid = true];
UUID(ハイフンなし32桁)の形式にしたいとき
value must be a valid trimmed UUID
string value = 1 [(buf.validate.field).string.tuuid = true];
IPアドレス+プレフィックス長(CIDR形式)にしたいとき
value must be a valid IP address with prefix length (e.g., 192.0.2.0/24)
string value = 1 [(buf.validate.field).string.ip_with_prefixlen = true];
IPv4アドレス+プレフィックス長にしたいとき
value must be a valid IPv4 address with prefix length
string value = 1 [(buf.validate.field).string.ipv4_with_prefixlen = true];
TimestampRules
特定の日時と完全に一致させたいとき
value must equal 2023-05-03T10:00:00Z
google.protobuf.Timestamp created_at = 1 [
(buf.validate.field).timestamp.const = { seconds: 1683108000 }
];
指定した日時より前でなければならないとき
value must be less than 2023-05-14T00:00:00Z
google.protobuf.Timestamp deadline = 1 [
(buf.validate.field).timestamp.lt = { seconds: 1684003200 }
];
指定した日時以前でなければならないとき
value must be less than or equal to 2023-05-14T00:00:00Z
google.protobuf.Timestamp deadline = 1 [
(buf.validate.field).timestamp.lte = { seconds: 1684003200 }
];
現在時刻より前でなければならないとき
value must be less than now
google.protobuf.Timestamp created_at = 1 [
(buf.validate.field).timestamp.lt_now = true
];
指定した日時より後でなければならないとき
value must be greater than 2023-01-01T00:00:00Z
google.protobuf.Timestamp started_at = 1 [
(buf.validate.field).timestamp.gt = { seconds: 1672531200 }
];
指定した日時以降でなければならないとき
value must be greater than or equal to 2023-01-01T00:00:00Z
google.protobuf.Timestamp started_at = 1 [
(buf.validate.field).timestamp.gte = { seconds: 1672531200 }
];
現在時刻より後でなければならないとき
value must be greater than now
google.protobuf.Timestamp expires_at = 1 [
(buf.validate.field).timestamp.gt_now = true
];
現在時刻 ± 指定時間内にある必要があるとき
value must be within 1 hour of now
google.protobuf.Timestamp scheduled_at = 1 [
(buf.validate.field).timestamp.within = { seconds: 3600 }
];
範囲指定(例:開始日時より後、終了日時より前)
value must be greater than 2023-01-01T00:00:00Z and less than 2023-01-02T00:00:00Z
google.protobuf.Timestamp meeting_time = 1 [
(buf.validate.field).timestamp = {
gt: { seconds: 1672531200 },
lt: { seconds: 1672617600 }
}
];
まとめ
いかがでしたでしょうか😊!
本記事では protovalidate の基本的な逆引きリファレンスをご紹介しました。
次回は、ignore や oneof など、より実践的で応用的な内容についても触れていければと思っています!
ぜひ引き続きチェックしていただけると嬉しいです〜!
Discussion