|
1 |
| -# [][buf] protovalidate-java |
| 1 | +[][buf] |
| 2 | + |
| 3 | +# protovalidate-java |
2 | 4 |
|
3 | 5 | [](https://github.com/bufbuild/protovalidate-java/actions/workflows/ci.yaml)
|
4 | 6 | [](https://github.com/bufbuild/protovalidate-java/actions/workflows/conformance.yaml)
|
5 | 7 | [][buf-mod]
|
6 | 8 |
|
7 |
| -`protovalidate-java` is the Java language implementation of [`protovalidate`](https://github.com/bufbuild/protovalidate) designed to validate Protobuf messages at runtime based on user-defined validation constraints. Powered by Google's Common Expression Language ([CEL](https://github.com/google/cel-spec)), 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. |
| 9 | +[Protovalidate][protovalidate] provides standard annotations to validate common constraints on messages and fields, as well as the ability to use [CEL][cel] to write custom constraints. It's the next generation of [protoc-gen-validate][protoc-gen-validate], the only widely used validation library for Protobuf. |
8 | 10 |
|
9 |
| -## The `protovalidate` project |
| 11 | +With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules: |
10 | 12 |
|
11 |
| -Head over to the core [`protovalidate`](https://github.com/bufbuild/protovalidate/) repository for: |
| 13 | +```protobuf |
| 14 | +syntax = "proto3"; |
12 | 15 |
|
13 |
| -- [The API definition](https://github.com/bufbuild/protovalidate/tree/main/proto/protovalidate/buf/validate/validate.proto): used to describe validation constraints |
14 |
| -- [Documentation](https://github.com/bufbuild/protovalidate/tree/main/docs): how to apply `protovalidate` effectively |
15 |
| -- [Migration tooling](https://github.com/bufbuild/protovalidate/tree/main/docs/migrate.md): incrementally migrate from `protoc-gen-validate` |
16 |
| -- [Conformance testing utilities](https://github.com/bufbuild/protovalidate/tree/main/docs/conformance.md): for acceptance testing of `protovalidate` implementations |
| 16 | +package banking.v1; |
| 17 | +
|
| 18 | +import "buf/validate/validate.proto"; |
17 | 19 |
|
18 |
| -Other `protovalidate` runtime implementations include: |
| 20 | +message MoneyTransfer { |
| 21 | + string to_account_id = 1 [ |
| 22 | + // Standard rule: `to_account_id` must be a UUID |
| 23 | + (buf.validate.field).string.uuid = true |
| 24 | + ]; |
19 | 25 |
|
20 |
| -- C++: [`protovalidate-cc`](https://github.com/bufbuild/protovalidate-cc) |
21 |
| -- Go: [`protovalidate-go`](https://github.com/bufbuild/protovalidate-go) |
22 |
| -- Python: [`protovalidate-python`](https://github.com/bufbuild/protovalidate-python) |
| 26 | + string from_account_id = 2 [ |
| 27 | + // Standard rule: `from_account_id` must be a UUID |
| 28 | + (buf.validate.field).string.uuid = true |
| 29 | + ]; |
23 | 30 |
|
24 |
| -And others coming soon: |
| 31 | + // Custom rule: `to_account_id` and `from_account_id` can't be the same. |
| 32 | + option (buf.validate.message).cel = { |
| 33 | + id: "to_account_id.not.from_account_id" |
| 34 | + message: "to_account_id and from_account_id should not be the same value" |
| 35 | + expression: "this.to_account_id != this.from_account_id" |
| 36 | + }; |
| 37 | +} |
| 38 | +``` |
25 | 39 |
|
26 |
| -- TypeScript: `protovalidate-ts` |
| 40 | +Once you've added `protovalidate-java` to your project, validation is idiomatic Java: |
| 41 | + |
| 42 | +```java |
| 43 | +ValidationResult result = validator.validate(message); |
| 44 | +if (!result.isSuccess()) { |
| 45 | + // Handle failure. |
| 46 | +} |
| 47 | +``` |
27 | 48 |
|
28 | 49 | ## Installation
|
29 | 50 |
|
30 |
| -To include `protovalidate-java` in your project, add the following to your build file: |
| 51 | +> [!TIP] |
| 52 | +> The easiest way to get started with Protovalidate for RPC APIs are the quickstarts in Buf's documentation. There's one available for [Java and gRPC][grpc-java]. |
| 53 | +
|
| 54 | +`protovalidate-java` is listed in [Maven Central][maven], which provides installation snippets for Gradle, Maven, and other package managers. In Gradle, it's: |
31 | 55 |
|
32 | 56 | ```gradle
|
33 | 57 | dependencies {
|
34 | 58 | implementation 'build.buf:protovalidate:<version>'
|
35 | 59 | }
|
36 | 60 | ```
|
37 | 61 |
|
38 |
| -Remember to always check for the latest version of `protovalidate-java` on the project's [GitHub releases page](https://github.com/bufbuild/protovalidate-java/releases) to ensure you're using the most up-to-date version. |
| 62 | +## Documentation |
39 | 63 |
|
40 |
| -## Usage |
| 64 | +Comprehensive documentation for Protovalidate is available in [Buf's documentation library][protovalidate]. |
41 | 65 |
|
42 |
| -### Implementing validation constraints |
| 66 | +Highlights for Java developers include: |
43 | 67 |
|
44 |
| -Validation constraints are defined directly within `.proto` files. Documentation for adding constraints can be found in the `protovalidate` project [README](https://github.com/bufbuild/protovalidate) and its [comprehensive docs](https://github.com/bufbuild/protovalidate/tree/main/docs). |
| 68 | +* The [developer quickstart][quickstart] |
| 69 | +* A comprehensive RPC quickstart for [Java and gRPC][grpc-java] |
| 70 | +* A [migration guide for protoc-gen-validate][migration-guide] users |
45 | 71 |
|
46 |
| -```protobuf |
47 |
| -syntax = "proto3"; |
| 72 | +## Additional Languages and Repositories |
48 | 73 |
|
49 |
| -package my.package; |
| 74 | +Protovalidate isn't just for Java! You might be interested in sibling repositories for other languages: |
50 | 75 |
|
51 |
| -import "google/protobuf/timestamp.proto"; |
52 |
| -import "buf/validate/validate.proto"; |
| 76 | +- [`protovalidate-go`][pv-go] (Go) |
| 77 | +- [`protovalidate-python`][pv-python] (Python) |
| 78 | +- [`protovalidate-cc`][pv-cc] (C++) |
| 79 | +- `protovalidate-es` (TypeScript and JavaScript, coming soon!) |
53 | 80 |
|
54 |
| -message Transaction { |
55 |
| - uint64 id = 1 [(buf.validate.field).uint64.gt = 999]; |
56 |
| - google.protobuf.Timestamp purchase_date = 2; |
57 |
| - google.protobuf.Timestamp delivery_date = 3; |
58 |
| - |
59 |
| - string price = 4 [(buf.validate.field).cel = { |
60 |
| - id: "transaction.price", |
61 |
| - message: "price must be positive and include a valid currency symbol ($ or £)", |
62 |
| - expression: "(this.startsWith('$') || this.startsWith('£')) && double(this.substring(1)) > 0" |
63 |
| - }]; |
64 |
| - |
65 |
| - option (buf.validate.message).cel = { |
66 |
| - id: "transaction.delivery_date", |
67 |
| - message: "delivery date must be after purchase date", |
68 |
| - expression: "this.delivery_date > this.purchase_date" |
69 |
| - }; |
70 |
| -} |
71 |
| -``` |
| 81 | +Additionally, [protovalidate's core repository](https://github.com/bufbuild/protovalidate) provides: |
72 | 82 |
|
73 |
| -### Example |
| 83 | +- [Protovalidate's Protobuf API][validate-proto] |
| 84 | +- [Conformance testing utilities][conformance] for acceptance testing of `protovalidate` implementations |
74 | 85 |
|
75 |
| -In your Java code, create an instance of the `Validator` class and use the `validate` method to validate your messages. |
76 | 86 |
|
77 |
| -```java |
78 |
| -// Import the required packages |
79 |
| -package build.buf; |
80 |
| - |
81 |
| -import build.buf.protovalidate.results.ValidationException; |
82 |
| -import build.buf.protovalidate.results.ValidationResult; |
83 |
| -import com.my.package.Transaction; |
84 |
| -import com.google.protobuf.Timestamp; |
85 |
| - |
86 |
| -import build.buf.protovalidate.Validator; |
87 |
| -import build.buf.protovalidate.Config; |
88 |
| - |
89 |
| -public class Main { |
90 |
| - |
91 |
| - // Create timestamps for purchase and delivery date |
92 |
| - Timestamp purchaseDate = Timestamp.newBuilder().build(); |
93 |
| - Timestamp deliveryDate = Timestamp.newBuilder().build(); |
94 |
| - |
95 |
| - // Create a transaction object using the Builder pattern |
96 |
| - Transaction transaction = |
97 |
| - Transaction.newBuilder() |
98 |
| - .setId(1234) |
99 |
| - .setPrice("$5.67") |
100 |
| - .setPurchaseDate(purchaseDate) |
101 |
| - .setDeliveryDate(deliveryDate) |
102 |
| - .build(); |
103 |
| - |
104 |
| - // Create a validator object with the default Configuration |
105 |
| - Validator validator = new Validator(); |
106 |
| - // Validate the transaction object using the validator |
107 |
| - try { |
108 |
| - ValidationResult result = validator.validate(transaction); |
109 |
| - |
110 |
| - // Check if there are any validation violations |
111 |
| - if (result.getViolations().isEmpty()) { |
112 |
| - // No violations, validation successful |
113 |
| - System.out.println("Validation succeeded"); |
114 |
| - } else { |
115 |
| - // Print the violations if any found |
116 |
| - System.out.println(result.toString()); |
117 |
| - } |
118 |
| - } catch (ValidationException e) { |
119 |
| - // Catch and print any ValidationExceptions thrown during the validation process |
120 |
| - System.out.println("Validation failed: " + e.getMessage()); |
121 |
| - } |
122 |
| -} |
123 |
| -``` |
| 87 | +## Contribution |
| 88 | + |
| 89 | +We genuinely appreciate any help! If you'd like to contribute, check out these resources: |
| 90 | + |
| 91 | +- [Contributing Guidelines][contributing]: Guidelines to make your contribution process straightforward and meaningful |
| 92 | +- [Conformance testing utilities](https://github.com/bufbuild/protovalidate/tree/main/docs/conformance.md): Utilities providing acceptance testing of `protovalidate` implementations |
124 | 93 |
|
125 |
| -### Ecosystem |
| 94 | +## Related Sites |
126 | 95 |
|
127 |
| -- [`protovalidate`](https://github.com/bufbuild/protovalidate) core repository |
128 |
| -- [Buf][buf] |
129 |
| -- [CEL Spec][cel-spec] |
| 96 | +- [Buf][buf]: Enterprise-grade Kafka and gRPC for the modern age |
| 97 | +- [Common Expression Language (CEL)][cel]: The open-source technology at the core of Protovalidate |
130 | 98 |
|
131 | 99 | ## Legal
|
132 | 100 |
|
133 | 101 | Offered under the [Apache 2 license][license].
|
134 | 102 |
|
135 |
| -[license]: LICENSE |
136 | 103 | [buf]: https://buf.build
|
| 104 | +[cel]: https://cel.dev |
| 105 | + |
| 106 | +[pv-go]: https://github.com/bufbuild/protovalidate-go |
| 107 | +[pv-java]: https://github.com/bufbuild/protovalidate-java |
| 108 | +[pv-python]: https://github.com/bufbuild/protovalidate-python |
| 109 | +[pv-cc]: https://github.com/bufbuild/protovalidate-cc |
| 110 | + |
| 111 | +[license]: LICENSE |
| 112 | +[contributing]: .github/CONTRIBUTING.md |
137 | 113 | [buf-mod]: https://buf.build/bufbuild/protovalidate
|
138 |
| -[cel-spec]: https://github.com/google/cel-spec |
| 114 | + |
| 115 | +[protoc-gen-validate]: https://github.com/bufbuild/protoc-gen-validate |
| 116 | + |
| 117 | +[protovalidate]: https://buf.build/docs/protovalidate |
| 118 | +[quickstart]: https://buf.build/docs/protovalidate/quickstart/ |
| 119 | +[connect-go]: https://buf.build/docs/protovalidate/quickstart/connect-go/ |
| 120 | +[grpc-go]: https://buf.build/docs/protovalidate/quickstart/grpc-go/ |
| 121 | +[grpc-java]: https://buf.build/docs/protovalidate/quickstart/grpc-java/ |
| 122 | +[grpc-python]: https://buf.build/docs/protovalidate/quickstart/grpc-python/ |
| 123 | +[migration-guide]: https://buf.build/docs/migration-guides/migrate-from-protoc-gen-validate/ |
| 124 | + |
| 125 | +[maven]: https://central.sonatype.com/artifact/build.buf/protovalidate/overview |
| 126 | +[pkg-go]: https://pkg.go.dev/github.com/bufbuild/protovalidate-go |
| 127 | + |
| 128 | +[validate-proto]: https://buf.build/bufbuild/protovalidate/docs/main:buf.validate |
| 129 | +[conformance]: https://github.com/bufbuild/protovalidate/blob/main/docs/conformance.md |
| 130 | +[examples]: https://github.com/bufbuild/protovalidate/tree/main/examples |
| 131 | +[migrate]: https://buf.build/docs/migration-guides/migrate-from-protoc-gen-validate/ |
0 commit comments