Validation
Validation catches bad input before a resolver runs. It complements GraphQL type coercion: coercion checks the shape, validation checks the domain rule.
Field values
#[graphql(validate = "path")] runs after coercion. On a field it receives &FieldType; on an
input type it receives &Self:
The error becomes a field error. gurafi also tags argument coercion and input validation with
extensions.code = "BAD_USER_INPUT" so server-side masking keeps the message visible.
Context-aware validation
Use FieldConfig::validate::<ArgsType>(...) when the rule needs the request context:
The type parameter must match the field's argument type. The hook runs after input-level validation and before the resolver. Arguments are coerced once; subscription events reuse the setup arguments and run the field validator once per event.
One-of inputs
#[graphql(one_of)] is both a shape and a validation rule: exactly one non-null field must be
provided. See Input objects.
Scalar validation
A custom scalar's ScalarValue::from_value is the validation hook for that scalar. Return an
error for an invalid representation; the error is attached to the argument or input field.
Plugin-based validation
A plugin can validate fields by path or metadata before calling next. This is useful for a rule
that is uniform across a group of fields, such as a required scope:
Use field-level .validate for argument-specific rules and plugins for cross-cutting policy.
Error handling
- Validation failures are GraphQL field errors with a response path.
- They do not panic and do not reach the resolver with unchecked data.
- Field-level auth and validation run before the resolver; a mock plugin that replaces the resolver skips both.
suku::mask_internalkeepsBAD_USER_INPUTandUNAUTHORIZEDmessages.
