[英]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不支持开箱即用的消息验证,但可以使用插件添加它(这是唯一的方法,但并不简单)。
您可以尝试查找现有插件,也可以创建自己的插件(如果您的语言没有现有的插件)。
如果您决定编写自己的插件,那么第一步是为字段定义自定义选项 :
package yourcompany;
import "google/protobuf/descriptor.proto";
extend google.protobuf.FieldOptions {
optional string validator = 51234;
}
此选项允许您为具体字段指定正则表达式。 然后,您应用新的自定义选项:
message Update {
string sensor_id = 1 [(yourcompany.validator) = "SENSOR-???????"];
// ...
}
其次,更具挑战性的步骤是编写自己的插件 ,以便为生成的代码添加验证逻辑:
此外,插件能够将代码插入其他代码生成器生成的文件中。 有关详细信息,请参阅plugin.proto中有关“插入点”的注释。 例如,这可用于编写一个插件,该插件生成为特定RPC系统定制的RPC服务代码。 请参阅每种语言中生成的代码的文档,以了解它们提供的插入点。
您的插件必须检查自定义选项的值,并为字段生成其他验证代码。
请检查此项目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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.