简体   繁体   English

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

[英]Protobuf3: String validation with regex

I have been using Protobuf3 to define a PB message: 我一直在使用Protobuf3来定义PB消息:

syntax = "proto3";
package vioozer_protobuf;

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

In my system, sensors have a unique id format (a-la SENSOR-1342r43 ) that can easily be validated with a regex. 在我的系统中,传感器具有唯一的id格式(a-la SENSOR-1342r43 ),可以使用正则表达式轻松验证。

Is there a way to add a regex validator to a protobuf field, so that only strings that adhere to the regex would be accepted into that field? 有没有办法将一个正则表达式验证器添加到protobuf字段,以便只有符合正则表达式的字符串才会被接受到该字段中?

Protobuf does not support message validation out of the box, but it is possible to add it using plugin (that's the only way, however, it is not simple). Protobuf不支持开箱即用的消息验证,但可以使用插件添加它(这是唯一的方法,但并不简单)。

You can try to find existing plugin, or create your own (if there is no existing plugin for your language). 您可以尝试查找现有插件,也可以创建自己的插件(如果您的语言没有现有的插件)。

If you decide to write your own plugin, then first step is to define a custom option for fields: 如果您决定编写自己的插件,那么第一步是为字段定义自定义选项

package yourcompany;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
    optional string validator = 51234;
}

This option allows you to specify regular expression for a concrete field. 此选项允许您为具体字段指定正则表达式。 Then you apply your new custom option: 然后,您应用新的自定义选项:

message Update {
    string sensor_id = 1 [(yourcompany.validator) = "SENSOR-???????"];
    // ...
}

Second, and more challenging step is to write your own plugin in order to add validation logic to generated code: 其次,更具挑战性的步骤是编写自己的插件 ,以便为生成的代码添加验证逻辑:

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. 有关详细信息,请参阅plugin.proto中有关“插入点”的注释。 This could be used, for example, to write a plugin which generates RPC service code that is tailored for a particular RPC system. 例如,这可用于编写一个插件,该插件生成为特定RPC系统定制的RPC服务代码。 See the documentation for the generated code in each language to find out what insertion points they provide. 请参阅每种语言中生成的代码的文档,以了解它们提供的插入点。

Your plugin must check value of your custom option and generate additional validation code for fields. 您的插件必须检查自定义选项的值,并为字段生成其他验证代码。

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

I wrote an example for Golang here https://github.com/alexcpn/golang_grpc_test 我在这里为Golang写了一个例子https://github.com/alexcpn/golang_grpc_test

With this you can give semantic validation as a annotation in proto and get it autogenerated as part of protobuff generation 有了这个,您可以将语义验证作为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.
}

Server validation using generated stub 使用生成存根的服务器验证

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM