• Stars
    star
    604
  • Rank 71,426 (Top 2 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created 12 months ago
  • Updated 29 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Protocol Buffer Validation - Go, Java, Python, and C++ Beta Releases!

protovalidate

CI Slack BSR

Update: The next generation of protoc-gen-validate, now called protovalidate, is available in beta for Golang, Python, Java, and C++! We're hard at work on a TypeScript implementations as well. To learn more, check out our blog post. We value your input in refining our products, so don't hesitate to share your feedback on protovalidate.

protovalidate is a series of libraries designed to validate Protobuf messages at runtime based on user-defined validation rules. Powered by Google's Common Expression Language (CEL), it provides a flexible and efficient foundation for defining and evaluating custom validation rules. The primary goal of protovalidate is to help developers ensure data consistency and integrity across the network without requiring generated code.

protovalidate is the spiritual successor to protoc-gen-validate. Looking for protoc-gen-validate? Checkout the original repository.

What is this repository?

This repository is the core of the protovalidate project. It contains:

Runtime implementations of protovalidate can be found in their own repositories:

Interested in adding support for another language? Check out our Contributing Guidelines.

Usage

Import protovalidate

To define constraints within your Protobuf messages, import buf/validate/validate.proto into your .proto files:

syntax = "proto3";

package my.package;

import "buf/validate/validate.proto";

Build with buf

Add a dependency on buf.build/bufbuild/protovalidate to your module's buf.yaml:

version: v1
# <snip>
deps:
  - buf.build/bufbuild/protovalidate
# <snip>

After modifying your buf.yaml, don't forget to run buf mod update to ensure your dependencies are up-to-date.

Build with protoc

Add an import path (-I flag) pointing to the contents of the proto/protovalidate directory to your invocation of protoc:

protoc \
  -I ./vendor/protovalidate/proto/protovalidate \
  # <snip>

Implementing validation constraints

Validation constraints can be enforced using the buf.validate Protobuf package. The rules are specified directly in the .proto files.

Let's consider a few examples:

  1. Scalar field validation: For a basic User message, we can enforce constraints such as a minimum length for the user's name.

    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];
    }
  2. Map field validation: For a Product message with a map of item quantities, we can ensure that all quantities are positive.

    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];
    }
  3. Well-known type (WKT) validation: For the User message, we can add a constraint to ensure the created_at timestamp is in the past.

    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];
    }

For more advanced or custom constraints, protovalidate allows for CEL expressions that can incorporate information across fields.

  1. Field-level expressions: We can enforce that a products' price, sent as a string, includes a currency symbol like "$" or "£". We want to ensure that the price is positive and the currency symbol is valid.

    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"
      }];
    }
  2. Message-level expressions: For a Transaction message, we can use a message-level CEL expression to ensure that the delivery_date is always after the 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"
      };
    }
  3. Producing an error message in the expression: We can produce custom error messages directly in the CEL expressions. In this example, if the age is less than 18, the CEL expression will evaluate to the error message string.

    syntax = "proto3";
    
    import "buf/validate/validate.proto";
    
    message User {
      int32 age = 1 [(buf.validate.field).cel = {
        id: "user.age",
        expression: "this.age < 18 ? 'User must be at least 18 years old': ''"
      }];
    }

Validate Messages

Once the messages are annotated with constraints, use one of the supported language libraries to validate; no additional code generation necessary.

Documentation

protovalidate provides a robust framework for validating Protobuf messages by enforcing standard and custom constraints on various data types, and offering detailed error information when validation violations occur. For a detailed overview of all its components, the supported constraints, and how to use them effectively, please refer to our comprehensive documentation. The key components include:

  • Standard Constraints: protovalidate supports a wide range of standard constraints for all field types as well as special functionality for the Protobuf Well-Known-Types. You can apply these constraints to your Protobuf messages to ensure they meet certain common conditions.

  • Custom Constraints: With Google's Common Expression Language (CEL), protovalidate allows you to create complex, custom constraints to handle unique validation scenarios that aren't covered by the standard constraints at both the field and message level.

  • Error Handling: When a violation occurs, protovalidateprovides detailed error information to help you quickly identify the source and fix for an issue.

protoc-gen-validate

protovalidate is the spiritual successor to protoc-gen-validate, offering all of the same functionality present in the original plugin, without the need for custom code generation, and the new ability to describe complex constraints in CEL.

protovalidate's constraints very closely emulate those in protoc-gen-validate to ensure an easy transition for developers. To migrate from protoc-gen-validate to protovalidate, use the provided migration tool to incrementally upgrade your .proto files.

Ecosystem

Legal

Offered under the Apache 2 license.

More Repositories

1

buf

The best way of working with Protocol Buffers.
Go
8,208
star
2

protoc-gen-validate

Protocol Buffer Validation - Being replaced by github.com/bufbuild/protovalidate
Go
3,638
star
3

connect-es

Connect, gRPC, and gRPC-Web support for Protobuf and TypeScript.
TypeScript
980
star
4

protobuf-es

Protocol Buffers for ECMAScript. The only JavaScript Protobuf library that is fully-compliant with Protobuf conformance tests.
TypeScript
927
star
5

protocompile

A parsing/linking engine for protobuf; the guts for a pure Go replacement of protoc.
Go
199
star
6

protovalidate-go

Protocol Buffer Validation for Go
Go
198
star
7

knit

GraphQL-like capabilities to services using Protocol Buffers, gRPC, and Connect
Go
136
star
8

buf-language-server

Prototype for a Protobuf language server compatible with Buf.
Go
116
star
9

connect-query

TypeScript-first expansion pack for TanStack Query that gives you Protobuf superpowers
TypeScript
109
star
10

makego

Makefile setup for our Golang projects.
Makefile
96
star
11

connect-opentelemetry-go

OpenTelemetry tracing and metrics for Connect
Go
81
star
12

connect-es-integration

Examples for using Connect with various TypeScript web frameworks and tooling
TypeScript
71
star
13

buf-examples

Example repository that uses Buf.
C#
69
star
14

connect-demo

An example service built with Connect.
Go
66
star
15

vscode-buf

Visual Studio Code integration for Buf.
TypeScript
56
star
16

connect-swift

Idiomatic gRPC & Connect RPCs for Swift.
Swift
48
star
17

knit-go

Knit standalone gateway and Go embeddable gateway
Go
45
star
18

prototransform

Client library for Buf Reflection API, for transforming Protobuf data.
Go
42
star
19

buf-gradle-plugin

Gradle plugin for the Buf CLI
Kotlin
42
star
20

connect-kotlin

Idiomatic gRPC & Connect RPCs for Kotlin.
Kotlin
42
star
21

buf-tour

Go
41
star
22

plugins

Remote Protobuf plugins available on the BSR
Dockerfile
40
star
23

connect-grpcreflect-go

gRPC-compatible server reflection for any net/http server.
Go
39
star
24

rules_buf

Bazel rules for Buf.
Starlark
37
star
25

vim-buf

Vim integration for Buf.
Vim Script
36
star
26

buf-setup-action

TypeScript
36
star
27

httplb

Client-side load balancing for net/http
Go
36
star
28

connect-grpchealth-go

gRPC-compatible health checks for any net/http server.
Go
32
star
29

buf-lint-action

TypeScript
28
star
30

protovalidate-python

Protocol Buffer Validation for Python.
Python
27
star
31

protovalidate-java

Protocol Buffer Validation for Java.
Java
26
star
32

knit-ts

TypeScript client for Knit
TypeScript
25
star
33

protoyaml-go

Marshal and unmarshal Protobuf as YAML with rich error messages.
Go
25
star
34

connect-crosstest

Connect's gRPC and gRPC-Web interoperability test suite.
C++
23
star
35

protobuf.com

Buf's Guide to Protobuf. Home of the language spec and grammar for the Protobuf IDL.
CSS
21
star
36

buf-breaking-action

TypeScript
20
star
37

protobuf-conformance

A repository running the Protobuf conformance tests against various libraries
JavaScript
20
star
38

modules

Collection of third-party modules managed and synced by Buf.
Go
19
star
39

buf-push-action

Shell
15
star
40

intellij-buf

IntelliJ plugin for Buf
Kotlin
15
star
41

protoplugin

The missing library to write protoc plugins.
Go
13
star
42

registry-proto

BSR's new public API. Currently in development.
Makefile
12
star
43

homebrew-buf

Homebrew tap for Buf.
Shell
12
star
44

protovalidate-cc

Protocol Buffer Validation for C++.
C++
11
star
45

docs.buf.build

The source for https://docs.buf.build.
TypeScript
11
star
46

protoschema-plugins

Protobuf plugins that generate various schemas from protobuf files - JSON Schema, PubSub, etc.
Go
10
star
47

tree-sitter-cel

Tree sitter grammar for the Common Expression Language (CEL)
C
9
star
48

wellknowntypes

All the Well-Known Types stored in per-version directories.
Go
9
star
49

connect-envoy-demo

Demonstration of how to use the new Connect-gRPC Envoy filter, available in Envoy v1.26+.
Go
8
star
50

reflect-proto

Protobuf reflection API.
7
star
51

knit-proto

Protocol definition for Knit
6
star
52

bufisk

Bazelisk, but for Buf. A user-friendly launcher for Buf.
Go
6
star
53

protobuf-language-spec

Comprehensive language specification for Protocol Buffers
5
star
54

knit-demo

An example service built with Knit
Go
4
star
55

jest-environment-jsdom

A modern jsdom test environment for Jest
TypeScript
4
star
56

tools

A collection of tools written at Buf.
JavaScript
4
star
57

base-workflows

Shared Github Actions for BufBuild Organization.
2
star
58

confluent-proto

Proto definitions for integrating Confluent Schema Registry with the BSR
Makefile
1
star
59

.github

1
star