Conversation
I'm not sure how I feel about this solution: - it's as lazy as possible to avoid late-bound types, which it does in the test cases we've got right now, but I don't think there's any guarantee? - it's so lazy it might just trigger during the first query execution rather than during schema boot, which seems bad and also leads to a random exception being raised because we have no good error-handling in this path - it's not cachable because it's context-dependent so it adds some small overhead of revalidation on every access of default_value
|
Does the default value need to be context dependent? Can you use a dummy context instead? |
|
We can use a dummy-value, which would make this cacheable, though that feels weird in the paths where we have a real context available still (which we definitely can't cache). The late-bound type handling and error/exception flow are bigger issues with this approach I think. |
| elsif default_value? | ||
| has_value = true | ||
| value = default_value | ||
| value = default_value(context) |
There was a problem hiding this comment.
@rmosolgo I'm looking at this a little more and I realize I'm confused. We call coerce_input on this value a few lines down, which at best is a no-op but (since this value should already be specified as ruby-land-objects and not graphql-syntax-input) would most likely fail entirely even on main branch without this PR? What am I missing?
There was a problem hiding this comment.
I'm admittedly fuzzy on the details but the intent here is to prepare some GraphQL input for handling by the application. (Eventually, argument_values here will populate a GraphQL::Execution::Interpreter::Arguments instance.) So, unless I've misunderstood, I'd expect type.coerce_input(...) below to prepare a GraphQL value for handling by Ruby. (Eg, turning enum strings into their value: ...s.)
But maybe that's the wrong approach for default_values, if they're already Ruby-style!
|
So barring my confusion (#3476 (comment)) about the way
This would still suffer from the issue that it definitely only triggers at first query execution to use the argument, but... better than nothing I guess? It also suffers from potential issues that other flows which use the default values (e.g. introspection, converting to/from SDL, etc) might just use the invalid default straight up still, since when they run we can't be confident that enough late-bound types are resolved to successfully validate it in the first place. How would this feel? |
|
Personally, I'm pretty keen on this. You're right that, annoyingly, you wouldn't find out that the default was invalid until a query comes in. But it's much simpler than trying to validate it at boot time, and making it context-dependent could come in handy. As for the first-query-might-raise-an-error problem, maybe you could work around that by calling |
|
FWIW 30722fb is a draft of the other variation I mentioned (do it only at runtime, don't use context so it's cacheable, use |
I'm not sure how I feel about this solution:
the test cases we've got right now, but I don't think there's any
guarantee?
rather than during schema boot, which seems bad and also leads to a
random exception being raised because we have no good error-handling in
this path
overhead of revalidation on every access of default_value
@rmosolgo @benjie this technically addresses #3248 and supersedes #3448 but... oof.