protovalidate
— это серия библиотек, предназначенных для проверки сообщений Protobuf во время выполнения на основе определяемых пользователем правил проверки. Основанный на общем языке выражений Google (CEL), он обеспечивает гибкую и эффективную основу для определения и оценки пользовательских правил проверки. Основная цель protovalidate
— помочь разработчикам обеспечить согласованность и целостность данных в сети без необходимости создания сгенерированного кода.
Примечание
protovalidate
является духовным преемником protoc-gen-validate. Он не требует генерации кода и поддерживает пользовательские ограничения.
Мы рекомендуем новым и существующим проектам перейти на использование protovalidate
вместо protoc-gen-validate
.
Прочтите сообщение в нашем блоге, если хотите узнать больше об ограничениях protoc-gen-validate
и о том, как мы сделали protovalidate
лучше.
Этот репозиторий является ядром проекта protovalidate
. Он содержит:
protovalidate
protoc-gen-validate
.proto
с использованием protovalidate
protovalidate
. Реализации protovalidate
во время выполнения можно найти в собственных репозиториях:
protovalidate-go
(бета-версия)protovalidate-cc
(бета-версия)protovalidate-java
(бета-версия)protovalidate-python
(бета-версия)protovalidate-ts
(скоро)Хотите добавить поддержку другого языка? Ознакомьтесь с нашими рекомендациями по участию.
Чтобы определить ограничения в сообщениях Protobuf, импортируйте buf/validate/validate.proto
в ваши файлы .proto
:
syntax = "proto3" ;
package my.package ;
import "buf/validate/validate.proto" ;
buf
Добавьте зависимость от buf.build/bufbuild/protovalidate
в buf.yaml
вашего модуля:
version : v1
#
deps :
- buf.build/bufbuild/protovalidate
#
После изменения вашего buf.yaml
не забудьте запустить buf mod update
чтобы убедиться, что ваши зависимости обновлены.
protoc
Добавьте путь импорта (флаг -I
), указывающий на содержимое каталога proto/protovalidate
при вызове protoc
:
protoc
-I ./vendor/protovalidate/proto/protovalidate
#
Ограничения проверки можно реализовать с помощью пакета buf.validate
Protobuf. Правила указаны непосредственно в файлах .proto
.
Давайте рассмотрим несколько примеров:
Проверка скалярного поля: для базового сообщения User
мы можем применять ограничения, такие как минимальная длина имени пользователя.
syntax = "proto3" ;
import "buf/validate/validate.proto" ;
message User {
// User's name, must be at least 1 character long.
string name = 1 [ (buf.validate .field ) .string .min_len = 1 ];
}
Проверка поля карты: для сообщения Product
с картой количеств товаров мы можем гарантировать, что все количества положительны.
syntax = "proto3" ;
import "buf/validate/validate.proto" ;
message Product {
// Map of item quantities, all quantities must be positive.
map < string , int32 > item_quantities = 1 [ (buf.validate .field ) .map.values.int32 .gt = 0 ];
}
Проверка общеизвестного типа (WKT). Для сообщения User
мы можем добавить ограничение, чтобы гарантировать, что временная метка created_at
находится в прошлом.
syntax = "proto3" ;
import "google/protobuf/timestamp.proto" ;
import "buf/validate/validate.proto" ;
message User {
// User's creation date must be in the past.
google.protobuf.Timestamp created_at = 1 [ (buf.validate .field ) .timestamp .lt_now = true ];
}
Для более сложных или пользовательских ограничений protovalidate
позволяет использовать выражения CEL, которые могут включать информацию из полей.
Выражения на уровне поля: мы можем обеспечить, чтобы price
продукта, отправленная в виде строки, включала символ валюты, например «$» или «£». Мы хотим убедиться, что цена положительна, а символ валюты действителен.
syntax = "proto3" ;
import "buf/validate/validate.proto" ;
message Product {
string price = 1 [ (buf.validate .field ).cel = {
id : "product.price" ,
message : "Price must be positive and include a valid currency symbol ($ or £)" ,
expression : "(this.startsWith('$') || this.startsWith('£')) && double(this.substring(1)) > 0"
}];
}
Выражения на уровне сообщения. Для сообщения Transaction
мы можем использовать выражение CEL на уровне сообщения, чтобы гарантировать, что delivery_date
всегда находится после purchase_date
.
syntax = "proto3" ;
import "google/protobuf/timestamp.proto" ;
import "buf/validate/validate.proto" ;
message Transaction {
google.protobuf.Timestamp purchase_date = 1 ;
google.protobuf.Timestamp delivery_date = 2 ;
option (buf.validate .message ).cel = {
id : "transaction.delivery_date" ,
message : "Delivery date must be after purchase date" ,
expression : "this.delivery_date > this.purchase_date"
};
}
Создание сообщения об ошибке в выражении. Мы можем создавать собственные сообщения об ошибках непосредственно в выражениях CEL. В этом примере, если age
меньше 18 лет, выражение CEL будет возвращать строку сообщения об ошибке.
syntax = "proto3" ;
import "buf/validate/validate.proto" ;
message User {
int32 age = 1 [ (buf.validate .field ).cel = {
id : "user.age" ,
expression : "this < 18 ? 'User must be at least 18 years old': ''"
}];
}
Ознакомьтесь с examples
как стандартных ограничений, так и пользовательских ограничений CEL.
После того как сообщения будут снабжены ограничениями, используйте для проверки одну из поддерживаемых языковых библиотек; дополнительная генерация кода не требуется.
protovalidate
предоставляет надежную основу для проверки сообщений Protobuf, применяя стандартные и пользовательские ограничения для различных типов данных и предлагая подробную информацию об ошибках при возникновении нарушений проверки. Подробный обзор всех его компонентов, поддерживаемых ограничений и способов их эффективного использования можно найти в нашей подробной документации. Ключевые компоненты включают в себя:
Стандартные ограничения : protovalidate
поддерживает широкий спектр стандартных ограничений для всех типов полей, а также специальную функциональность для Protobuf Well-Known-Types. Вы можете применить эти ограничения к своим сообщениям Protobuf, чтобы гарантировать, что они соответствуют определенным общим условиям.
Пользовательские ограничения : с помощью общего языка выражений Google (CEL) protovalidate
позволяет создавать сложные пользовательские ограничения для обработки уникальных сценариев проверки, которые не охватываются стандартными ограничениями как на уровне поля, так и на уровне сообщения.
Обработка ошибок : при возникновении нарушения protovalidate
предоставляет подробную информацию об ошибке, которая поможет вам быстро определить источник и устранить проблему.
protovalidate
является духовным преемником protoc-gen-validate
, предлагая все те же функции, что и исходный плагин, без необходимости генерации специального кода и новую возможность описывать сложные ограничения в CEL.
Ограничения protovalidate
очень точно имитируют ограничения protoc-gen-validate
чтобы обеспечить легкий переход для разработчиков. Чтобы перейти с protoc-gen-validate
на protovalidate
, используйте предоставленный инструмент миграции для постепенного обновления файлов .proto
.
Предлагается по лицензии Apache 2.