-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Default coercion and validation is... inconsistent #3459
Comments
Looks like I ran into part of this same issue way back in 2016 😂 😬 |
Thanks for writing up this issue, it certainly reflects the one-patch-at-a-time approach to development 😆 But if it only comes up once every 5 years, that's not too bad! I can share my own opinion on the questions above:
In my opinion, the best would be a choice. A similar question exists for non-null validations: should GraphQL-Ruby guarantee that the schema never violates the spec? I think that's a good default behavior. But at the same time, it'd be nice to offer the option to remove that validation for when devs want to reduce the overhead of execution.
I definitely think it'd be worth revisiting this. Another problem is accepting input from query string parameters, where everything is a string. It'd be nice to have a way to support more forgiving coercion in that case, but there isn't one now. Also worth noting is the difficulty between literal validators, which can be validated statically, and variable values, which take a different codepath. I suspect that some of the current complexity arose from that difficulty (although it could probably be done better!).
The most compelling reason for |
Without digging too much into the implications my default preference would be:
I still need to think about literals-vs-variables, typed-vs-strings, etc. That part is definitely messy. |
@rmosolgo another spin out of #3448. Filing as an issue not a PR because this might have implications across many classes, and probably needs some discussion.
The built-in scalars are confusingly inconsistent in what they will coerce for output, and how they produce errors.
Int
scalar usesto_i
when coercing outputs and then callsschema.type_error
if the resulting int is out of bounds (GraphQL requires ints to be in the 32-bit signed range). In ruby"non_numeric_string".to_i
produces0
, not an error.BigInt
andFloat
behave similarly, thoughFloat
is not bounded (which I believe it should be?)Boolean
is even more liberal, it just runs!!
which as far as I know will convert any ruby object of any type whatsoever into a boolean.ID
, similarly, just callsto_s
which is a method that exists on every ruby object (evennil.to_s
returns""
).ISO8601Date
usesDate.parse
which I believe raises errors on invalid arguments?ISO8601DateTime
usesTime.parse
which raises on invalid arguments, but then rescues all exceptions and converts them intoGraphQL::Error
s.JSON
is the best yet, it does a complete literal pass-through:graphql-ruby/lib/graphql/types/json.rb
Lines 20 to 22 in 5ab3e5e
String
callsto_s
but then validates the string is in UTF-8 (mutating the passed-in string if it isn't frozen!?) and reports encoding errors using theschema.type_error
callback.All of these are inconsistent with each other, but also with scalar coercion on input where AFAICT the best practice is for your coercion method to return
nil
on invalid input?Questions
schema.type_error
? Returning nil?I think whatever our answers to the above, some of the default scalars will need changing.
cc @benjie @swalkinshaw
The text was updated successfully, but these errors were encountered: