Description
This issue is part-feature request and part-inquiry as to how this pattern can best be achieved:
When an argument is passed to a field, have the argument's value be accessible to only the "sub-fields" in the subsequent tree of fields that are queried from that point.
Here's an example of having a configuration value like a session ID be accessible for every field under the one in which the session is provided.
query problemDomain {
a(configurationValue: "1"){ # before hook to set configuration value
aa { # is aware of configurationValue "1"
ab # is aware of configurationValue "1"
}
ac # is aware of configurationValue "1"
} # after hook to unset configuration value
b { # nothing to set
ba { # has no configurationValue
bb # has no configurationValue
}
bc # has no configurationValue
} # nothing to unset
c(configurationValue: "2") { # before hook to set configuration value
ca { # is aware of configurationValue "2"
cb # is aware of configurationValue "2"
}
cc # is aware of configurationValue "2"
} # after hook to unset configuration value
}
This example relies on this propagation occurring and having a trigger or hook to stop the propagation at the end of a field's "round-trip" and unset the configuration value.
I've found this requirement conceptually similar to middleware, a useful pattern often seen in the Node.js and Elixir worlds to avoid manipulating global mutable states from any arbitrary point within the request. I can imagine a similar concept being applied here, but instead of at the request level, at the field/resolver level. Some of the use cases off the top of my head:
- Session management (see above)
- Logging
- Benchmarking
- Prefetching and caching dependent objects
- Parsing inputs and context
- Authentication
graphql-ruby
already offers field extensions as a concept, which are similar in nature to what this is attempting to solve, but the after_resolve
hook only triggers immediately after a field's resolver, not on the field's "round-trip".
From what I can tell, without a primitive, the only option for enabling this sort of pattern is to change the backing model of all GraphQL objects to be a decorator which can manually propagate the argument value through every resolver. Even then, this approach only solves the session management / configuration value use case, and doesn't address any case which relies on an explicit after_round_trip
hook.
Hoping to get some feedback on the general pattern, whether there are any other viable options for enabling such use cases, and whether such a primitive would make sense alongside constructs like field extensions. Thanks!