
protovalidate — это серия библиотек, предназначенных для проверки сообщений Protobuf во время выполнения на основе определяемых пользователем правил проверки. Основанный на общем языке выражений Google (CEL), он обеспечивает гибкую и эффективную основу для определения и оценки пользовательских правил проверки. Основная цель protovalidate — помочь разработчикам обеспечить согласованность и целостность данных в сети без необходимости создания сгенерированного кода.
Примечание
protovalidate является духовным преемником protoc-gen-validate. Он не требует генерации кода и поддерживает пользовательские ограничения.
Мы рекомендуем новым и существующим проектам перейти на использование protovalidate вместо protoc-gen-validate .
Прочтите сообщение в нашем блоге, если хотите узнать больше об ограничениях protoc-gen-validate и о том, как мы сделали protovalidate лучше.
Этот репозиторий является ядром проекта protovalidate . Он содержит:
protovalidateprotoc-gen-validate.proto с использованием protovalidateprotovalidate . Реализации 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
# <snip>
deps :
- buf.build/bufbuild/protovalidate
# <snip> После изменения вашего buf.yaml не забудьте запустить buf mod update чтобы убедиться, что ваши зависимости актуальны.
protoc Добавьте путь импорта (флаг -I ), указывающий на содержимое каталога proto/protovalidate при вызове protoc :
protoc
-I ./vendor/protovalidate/proto/protovalidate
# <snip> Ограничения проверки можно реализовать с помощью пакета Protobuf buf.validate . Правила указаны непосредственно в файлах .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.