Protobuf3: проверка строк с помощью регулярных выражений
Я использовал Protobuf3 для определения сообщения PB:
syntax = "proto3";
package vioozer_protobuf;
message Update
{
string sensor_id = 1;
...
}
В моей системе датчики имеют уникальный формат идентификатора (а-ля SENSOR-1342r43
) это можно легко проверить с помощью регулярного выражения.
Есть ли способ добавить валидатор регулярных выражений в поле protobuf, чтобы в это поле могли приниматься только строки, привязанные к регулярному выражению?
1 ответ
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
Я написал пример для Голанга здесь 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)