Protovalidate is the semantic validation library for Protobuf. It provides standard annotations to validate common rules on messages and fields, as well as the ability to use CEL to write custom rules. It's the next generation of protoc-gen-validate.
With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules:
syntax = "proto3";
package acme.user.v1;
import "buf/validate/validate.proto";
message User {
string id = 1 [(buf.validate.field).string.uuid = true];
uint32 age = 2 [(buf.validate.field).uint32.lte = 150]; // We can only hope.
string email = 3 [(buf.validate.field).string.email = true];
string first_name = 4 [(buf.validate.field).string.max_len = 64];
string last_name = 5 [(buf.validate.field).string.max_len = 64];
option (buf.validate.message).cel = {
id: "first_name_requires_last_name"
message: "last_name must be present if first_name is present"
expression: "!has(this.first_name) || has(this.last_name)"
};
}
Once you've added @bufbuild/protovalidate
to your project, validation is simple:
import { create } from "@bufbuild/protobuf";
import { createValidator } from "@bufbuild/protovalidate";
import { MoneyTransferSchema } from "./gen/banking_pb";
const transfer = create(MoneyTransferSchema);
const validator = createValidator();
const result = validator.validate(MoneyTransferSchema, transfer);
if (result.kind !== "valid") {
// Handle failure.
}
Tip
The string.pattern
rule supports regular expressions with CEL's standard RE2 syntax.
Protovalidate translates RE2 to ECMAScript's regular expressions. This works except for some RE2 flags, but it cannot support RE2's most important property: Execution in linear time, which guards against ReDoS.
If you need full support for RE2, you can bring your own RE2 implementation:
const validator = createValidator({
regexMatch: (pattern: string, against: string): boolean => new RE2(pattern).test(against),
});
- @bufbuild/protovalidate: Validates Protobuf messages at runtime based on user-defined validation rules.
Note that protovalidate-es requires the Protobuf runtime @bufbuild/protobuf.
Protovalidate isn't just for ECMAScript! You might be interested in sibling repositories for other languages:
protovalidate-go
(Go)protovalidate-java
(Java)protovalidate-python
(Python)protovalidate-cc
(C++)
Additionally, protovalidate's core repository provides:
- Protovalidate's Protobuf API
- Example
.proto
files usingprotovalidate
- Conformance testing utilities for acceptance testing of
protovalidate
implementations
We genuinely appreciate any help! If you'd like to contribute, check out these resources:
- Contributing Guidelines: Guidelines to make your contribution process straightforward and meaningful
- Conformance testing utilities: Utilities providing acceptance testing of
protovalidate
implementations - Protovalidate-ES conformance executor: Conformance testing executor
Offered under the Apache 2 license.