-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] unique repeated messages by field #92
Comments
@derekperkins what you're proposing is meant to support this right? (copied from Suppose I have an array of messages with field
Have you found a way to get this behavior with the current API? |
Yes, this is exactly the use case I'm suggesting. No, I haven't solved this today with protovalidate, but I'm interested to hear back if you find a good workaround |
You may be able to get away with this using what's available in CEL today on
This uses the |
I was able to get this to work by specifying the CEL expression on a message, rather than the repeated field. Here is a code sample: message Environment {
option (buf.validate.message).cel = {
id: "repeated.unique_by_field"
message: "repeated value must contain unique items, identified by the name field"
expression: "this.variables.map(v, v.name).unique()"
};
// Variables to use within the environment. Each variable must have a unique `name` field.
repeated EnvVar variables = 1;
// [(buf.validate.field).cel = {
// id: "repeated.unique_by_field"
// message: "repeated value must contain unique items, identified by the name field"
// expression: "this.map(v, v.name).unique()"
// }];
}
message EnvVar {
// Name of the environment variable. Must be unique.
string name = 1;
// Value of the environment variable.
string value = 2;
} The "violations": [
{
"fieldPath": "environment",
"constraintId": "repeated.unique_by_field",
"message": "repeated value must contain unique items, identified by the name field"
}
] However, as you might have noticed. The If we use the
Assuming that the issue preventing the expression from being evaluated on the repeated field itself is resolved, there is just one other issue. Which is handling what field needs to be unique. The constraint ID can be used for localization, but right now it is just a generic |
After looking at different ways of doing this, could we perhaps have an annotation to mark unique fields:
We could set a restriction on the types of the fields in unique.keys. Say it would be simplest if we only allow:
Do you think this could work? |
@matthewpi, I think this is a bug on protovalidate-go's part (likely in the type checking). This should have worked. I'll take a look and see if I can repro and add some tests for it. [Edit: protovalidate-go#80]
@matthewpi, there's #17 and #125 which aim to make it easier to get at the underlying info of a violation error. That said, with a custom CEL expression, you have control over the id and error message and can even construct it within the expression to use string formatting against the variables provided: repeated EnvVar variables = 1 [(buf.validate.field).cel = {
id: "env.vars.unique", // the ID can be very specific to the field in question
expression: "this.map(v, v.name).unique() ? '' : 'variables are expected to be unique, got %s'.format([this.map(v, v.name)])"
} We intentionally do not include any data in the standard constraint error messages or as part of the violation error as there are security and PII concerns with echoing potentially sensitive data. You are free to do so in custom expressions however, and we're planning to address the linked issues above in the near term.
@mivanovcpd, a multi-field uniqueness comparison can be problematic for languages that don't have equivalents of Java's That said, if we can determine a way to make this universally efficient and not a performance landmine, either in the case of uniqueness across the entire message or a subset of fields (using a FieldMask WKT for this would offer the most flexibility), I'm open to adding such a standard constraint. |
The way we were resolving the CEL types for type-checking expressions was inconsistent between custom and standard constraints. Resulting in compilation errors (particularly around repeated fields). Logic shared between the two (mostly lookups) was moved into the `expression` internal package and used uniformly for both environments. This also improves on a previously discovered bug around the Any WKT where custom expressions against such a field would fail with a runtime error if its underlying type was not known to CEL (CEL treats Any's as the underlying type, instead of the Any message itself). The standard constraints on Any do not have this limitation. We are populating the root CEL environment with `protoregistry.GlobalFiles` for now, but will likely make this configurable in the long-run. Context: bufbuild/protovalidate#92 (comment) (h/t @matthewpi)
For repeated items, CEL types were being miscalculated for variables in the expression resulting in type-check/compilation errors Fixes bufbuild#91
Feature description:
There's already a built in rule for scalar uniqueness in repeated fields. Most repeated messages have an id field that defines uniqueness, that could be used.
https://github.com/bufbuild/protovalidate/blob/main/proto/protovalidate/buf/validate/validate.proto#L3199-L3213
Proposed implementation or solution:
This isn't valid CEL, just a rough description of what I'm expecting
Contribution:
Minimal time to contribute currently
The text was updated successfully, but these errors were encountered: