Protobuf3:使用正则表达式验证字符串
Protobuf3: String validation with regex
我一直在使用Protobuf3定义PB消息:
syntax = "proto3";
package vioozer_protobuf;
message Update
{
string sensor_id = 1;
...
}
在我的系统中,传感器具有唯一的 ID 格式 (a-la SENSOR-1342r43
),可以使用正则表达式轻松验证。
有没有办法将正则表达式验证器添加到 protobuf 字段,以便只有符合正则表达式的字符串才会被该字段接受?
Protobuf 不支持开箱即用的消息验证,但可以使用插件添加它(这是唯一的方法,但并不简单)。
您可以尝试查找现有插件,或创建您自己的插件(如果没有适合您的语言的现有插件)。
如果您决定编写自己的插件,那么第一步是为字段定义 a custom option:
package yourcompany;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FieldOptions {
optional string validator = 51234;
}
此选项允许您为具体字段指定正则表达式。然后应用新的自定义选项:
message Update {
string sensor_id = 1 [(yourcompany.validator) = "SENSOR-???????"];
// ...
}
其次,更具挑战性的步骤是 write your own plugin 以便将验证逻辑添加到生成的代码中:
Additionally, plugins are able to insert code into the files generated by other code generators. See the comments about "insertion points" in plugin.proto for more on this. This could be used, for example, to write a plugin which generates RPC service code that is tailored for a particular RPC system. See the documentation for the generated code in each language to find out what insertion points they provide.
您的插件必须检查自定义选项的值并为字段生成额外的验证代码。
请检查这个项目 protoc-gen-validate https://github.com/envoyproxy/protoc-gen-validate
我在这里写了一个 Golang 的例子https://github.com/alexcpn/golang_grpc_test
有了这个,你可以在 proto 中将语义验证作为注释,并让它作为 protobuff 生成的一部分自动生成
message SearchRequest {
string query = 1 [(validate.rules).string = {
pattern: "([A-Za-z]+) ([A-Za-z]+)*$",
max_bytes: 50,
}];
string email_id= 2 [(validate.rules).string.email = true];
int32 page_number = 3; // Which page number do we want?
int32 result_per_page = 4; // Number of results to return per page.
}
使用生成的存根进行服务器验证
func (s *Server)Search(ctx context.Context, in *pb.SearchRequest) (*pb.SearchResponse, error){
log.Printf("Received Emailid: %v", in.EmailId)
log.Printf("Received Query: %v", in.Query)
// Note this is the only place we use validate
err := in.Validate()
if err != nil {
log.Warn("SearchRequest validation failed: %v", err)
我一直在使用Protobuf3定义PB消息:
syntax = "proto3";
package vioozer_protobuf;
message Update
{
string sensor_id = 1;
...
}
在我的系统中,传感器具有唯一的 ID 格式 (a-la SENSOR-1342r43
),可以使用正则表达式轻松验证。
有没有办法将正则表达式验证器添加到 protobuf 字段,以便只有符合正则表达式的字符串才会被该字段接受?
Protobuf 不支持开箱即用的消息验证,但可以使用插件添加它(这是唯一的方法,但并不简单)。
您可以尝试查找现有插件,或创建您自己的插件(如果没有适合您的语言的现有插件)。
如果您决定编写自己的插件,那么第一步是为字段定义 a custom option:
package yourcompany;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FieldOptions {
optional string validator = 51234;
}
此选项允许您为具体字段指定正则表达式。然后应用新的自定义选项:
message Update {
string sensor_id = 1 [(yourcompany.validator) = "SENSOR-???????"];
// ...
}
其次,更具挑战性的步骤是 write your own plugin 以便将验证逻辑添加到生成的代码中:
Additionally, plugins are able to insert code into the files generated by other code generators. See the comments about "insertion points" in plugin.proto for more on this. This could be used, for example, to write a plugin which generates RPC service code that is tailored for a particular RPC system. See the documentation for the generated code in each language to find out what insertion points they provide.
您的插件必须检查自定义选项的值并为字段生成额外的验证代码。
请检查这个项目 protoc-gen-validate https://github.com/envoyproxy/protoc-gen-validate
我在这里写了一个 Golang 的例子https://github.com/alexcpn/golang_grpc_test
有了这个,你可以在 proto 中将语义验证作为注释,并让它作为 protobuff 生成的一部分自动生成
message SearchRequest {
string query = 1 [(validate.rules).string = {
pattern: "([A-Za-z]+) ([A-Za-z]+)*$",
max_bytes: 50,
}];
string email_id= 2 [(validate.rules).string.email = true];
int32 page_number = 3; // Which page number do we want?
int32 result_per_page = 4; // Number of results to return per page.
}
使用生成的存根进行服务器验证
func (s *Server)Search(ctx context.Context, in *pb.SearchRequest) (*pb.SearchResponse, error){
log.Printf("Received Emailid: %v", in.EmailId)
log.Printf("Received Query: %v", in.Query)
// Note this is the only place we use validate
err := in.Validate()
if err != nil {
log.Warn("SearchRequest validation failed: %v", err)