prost
prost copied to clipboard
Implementing validation for prost -generated structs
This is not a bug report or feature request, but rather a question about practical approaches for implementing validation for prost -generated structs (as a part of tonic grpc service).
Use case: I'd like to validate the user-submitted struct data on the server side (e.g. matches regexp, max length, etc.).
Possible ways to resolve this:
1. Create a new trait & implement it on structs
trait MyValidator {
fn validate() -> bool;
}
impl MyValidator for MyProstStruct {
fn validate(&self) -> bool {
if !self.email.contains("@") {
return false;
}
// ... etc
true
}
}
2. Use existing validation framework with derive-macros
For example, https://crates.io/crates/validator. The syntax for validator is:
#[derive(Debug, Validate, Deserialize)]
struct SignupData {
#[validate(email)]
mail: String
}
this brings a problem, how to actually have prost generate the required macro-markup per struct field. There is config.field_attribute(...) (https://docs.rs/prost-build/0.6.1/prost_build/struct.Config.html#method.field_attribute), but having the actual .proto files and the validation-derives separated in multiple files is hard to manage. Do .proto files have some way to supply metadata per field?
I looked for other alternative frameworks, but could not find one with moderate+ adoption rate.
3. Use existing validation framework without macros
Validator seems to support this, partly, but for example regex validation is missing.
Conclusion
Any ideas, how to proceed with this?
I'm not aware of any widely used 'semantic' validation tools that are used across languages for protobuf. That being said it's been a pain point I've felt in any moderately complex system using protobufs, so I'm certainly open to ideas.
One could use custom field options to define the validation for a field. For example, one could have a a very generic custom field option like prost_field_attribute that would translate to the equivalent of calling field_attribute on that field.
Example:
message Foo {
string bar = 1 [(prost_field_attribute) = "#[validate(email)]"];
}
If custom field options get more support, one could perhaps build a more sophisticated companion library prost-validate.
I think it'd have to work at the Message level, since quite often you also want to do cross field validations, i.e. 'the sum of fields a and b must be even'
There seems to be a standard developing around https://github.com/envoyproxy/protoc-gen-validate
There seems to be a standard developing around https://github.com/envoyproxy/protoc-gen-validate
But it does not have any rust code generator. Why not use this rust validator? https://github.com/KaiserKarel/prosit