I would like to know what is the best place to put validation to the input parameter for the query for example
{
user(email: "useremail"){
}
}
I want to make sure the passed in email is in the correct format, what is the best place to validate that?
while we are resolving the data? or there is some other options there?
You can use a ValidationRule for this to validate the inputs before it attempts to execute the query. Here's one of the core validation rules used for the GraphQL spec that deals with Arguments:
You can pass the validation rules you want to run to the DocumentExecutor.
var executor = new DocumentExecutor();
var result = await executer.ExecuteAsync(_ =>
{
_.Schema = schema;
_.Query = request.Query;
...
_.ValidationRules =
DocumentValidator.CoreRules().Concat(new[]{ new EmailValidationRule() });
});
You could add metadata to the QueryArgument to provide a more generic way to configure what validations should be done for that argument, and use some validation library to do the actual check against the given value.
Thanks very much to your reply @joemcbride .
You mentioned about adding metadata to the QueryArgument, how is that done in the library? Currently, my argument is StringGraphType, do I need to create the argument as a separated type and then put the meta data there or I can just configure that when I defined the QueryArgument?
Thanks
I would say to add the metadata to the QueryArgument. QueryArgument does not currently have built-in metadata like fields and objects do but should be able to add it.
This is what I was thinking:
public class MyQueryArgument<T> : QueryArgument<T>, IProvideMetadata
{
// members of IProvideMetadata
IDictionary<string, object> Metadata { get; }
TType GetMetadata<TType>(string key, TType defaultValue = default(TType));
bool HasMetadata(string key);
}
public static class ArgumentValidationExtensions
{
public static QueryArgument IsEmail(this QueryArgument argument)
{
argument.Metadata["validator"] = "EMAIL_VALIDATOR";
return argument;
}
}
arguments: new QueryArguments(new MyQueryArgument<StringGraphType>().IsEmail())
Then in your ValidationRule you can check to see if the QueryArgument has any associated validations.
Some pseudo code:
// in the ValidationRule
var argumentAst = ... // this is an Argument from the executed query
var argument = ... // this is a QueryArgument from the Schema
var validator = GetValidator(argument);
var value = GetValue(argumentAst, argument, context.Inputs); // context is ValidationContext
var validationResults = validator.Validate(value);
// add any errors to ValidationContext as needed
Thanks for your information on this.
Most helpful comment
You can use a
ValidationRulefor this to validate the inputs before it attempts to execute the query. Here's one of the core validation rules used for the GraphQL spec that deals with Arguments:https://github.com/graphql-dotnet/graphql-dotnet/blob/3f2355aacd6cfd8e080dba1d802b2fa00f958f85/src/GraphQL/Validation/Rules/ArgumentsOfCorrectType.cs#L14-L38
You can pass the validation rules you want to run to the
DocumentExecutor.You could add metadata to the
QueryArgumentto provide a more generic way to configure what validations should be done for that argument, and use some validation library to do the actual check against the given value.