-
Notifications
You must be signed in to change notification settings - Fork 2k
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
parameterized query variable values aren't passed to parseLiteral of GraphQLScalarTypes #433
Comments
This is correct behavior - I'm curious to know what code or docs you read that lead you to this? I'd like to improve them to avoid this confusion in the future.
Since |
However - unrelated to your issue but just a point of critique based on best practices: Custom scalars are really intended to be used when the underlying programming environment contains a type of scalar which is semantically meaningfully different which you want to expose via your API (e.g. Floats vs Ints). Emails, Passwords, Usernames, etc are typically all easily represented internally as |
Okay, that makes sense, the docs don't go into much detail about I got this idea from Meatier, which defines custom scalars for emails, passwords, URLs, etc. I'll let Matt Krick, the maintainer, know... |
@leebyron I think this kind of confusion could persist without careful wording in the documentation. For instance, who would consider a query with |
@leebyron plus I can understand the temptation to use GraphQL for all validation, for the sake of not having to write a second layer of validation. |
If it's easy enough to use GraphQL for all validation, it might become common... |
I suppose so - in my opinion it's a mental burden cost on someone using your API in exchange for reduced work on behalf of the server, usually a bad trade. In my experience I've found validation being documented and implemented relative to field arguments to be easier to follow. I think this probably is a good argument in favor of some of the ideas discussed in #361 around providing better input validation functionality without requiring the creation of new scalar types. Honestly though it's a fairly minor point, I don't think you're likely to end up with any serious issues because of custom scalars vs any other form of input validation. There are definitely pros and cons to all approaches here and I should be careful to speak too much about best practices while GraphQL is still a young technology :) |
I don't completely understand your first paragraph there, if GraphQLScalars validate fields isn't that literally validation "implemented relative to field arguments"? And I don't understand how it would affect the documentation. For instance explaining what emails and passwords are valid is independent of how the validation is implemented. Or are you saying that the structure of error messages would change and that would be harder to document? |
Sorry for the confusion, let me restate. Validation relative to field arguments would be defining the validation rules next to the field argument itself, this is what was proposed in #361. field: {
type: WhateverType,
args: {
someArg: { type: String }
}
resolve(obj, { someArg }) {
if (!myValidationFn(someArg)) {
throw new Error('Informative message');
}
// ...
}
} This in contrast to implementing validation relative to types which is what defining types for each kind of input is doing. As per documentation, it's mostly a question about knowing what is or isn't allowed for a given type. E.g. if I had a custom scalar called |
Ah gotcha. Yeah that makes sense. Here's why I'm leaning toward validation relative to types though: validation relative to the field makes a semantic distinction between the type and the valid forms of that type for that field. But all types have a specific set of valid forms to begin with, so is it a useful distinction? In my mind, it's simpler to just represent emails as a separate type. Besides, it's an easier way to ensure that my queries never get run with invalid emails (if I use validation relative to fields, I have to refer to my email validator in every email field in any query). Now if it comes down to checking that a field makes sense in the environment, e.g. checking if an email is in the system, I definitely wouldn't want to check that in a custom scalar. But any restrictions that don't depend on context seem inherent to the type to me. |
@leebyron since exploring this more I've realized that it's not very easy with custom scalars to generate errors that indicate which field was invalid. I guess it might be possible for GraphQL to return the field name in the errors someday, but for the time being I've just gone back to validating arguments in |
Closing this as I believe the original question was answered. |
When I call my login method like this, it calls my Password type's
parseLiteral
method which throws an error as expected:Result:
But if I change that to a parameterized query with the same values in the variables, it never calls my Password type's
parseLiteral
, and it succeeds. Am I misunderstanding something, or is this a bug? I couldn't find anything in the documentation about different validation behavior for parameterized queries.Variables:
Result:
Here is my Password type:
And the login query schema:
The text was updated successfully, but these errors were encountered: