Protobuf3:使用正则表达式进行字符串验证

时间:2016-10-05 11:52:52

标签: regex string validation protocol-buffers protobuf-3

我一直在使用Protobuf3来定义PB消息:

syntax = "proto3";
package vioozer_protobuf;

message Update
{
  string sensor_id = 1;
  ...
}

在我的系统中,传感器具有唯一的ID格式(a-la SENSOR-1342r43),可以使用正则表达式轻松验证。

有没有办法在protobuf字段中添加正则表达式验证程序,以便只有符合正则表达式的字符串才会被接受到该字段中?

2 个答案:

答案 0 :(得分:7)

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,以便为生成的代码添加验证逻辑:

  

此外,插件能够将代码插入其他代码生成器生成的文件中。请参阅有关"插入点"的评论。在plugin.proto了解更多信息。例如,这可用于编写一个插件,该插件生成为特定RPC系统定制的RPC服务代码。请参阅每种语言中生成的代码的文档,以了解它们提供的插入点。

您的插件必须检查自定义选项的值,并为字段生成其他验证码。

答案 1 :(得分:0)

请检查此项目protoc-gen-validate https://github.com/envoyproxy/protoc-gen-validate

我在https://github.com/alexcpn/golang_grpc_test

上为Golang写了一个例子

借助此方法,您可以在原型中进行语义验证作为注释,并在原型生成过程中自动生成它

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)