feature request: Support multiple registered GraphQLContext contributors, allowing them to provide GraphQLContext key/value entries
Feature Request
In https://github.com/graphql-java/graphql-java/pull/2368, GraphQLContext was added to replace context, with the intent to allow code both in userspace and frameworks to contribute to, share and leverage the content in the GraphQLContext.
In https://github.com/Netflix/dgs-framework/pull/982, DGS has been adjusted to support using getGraphQlContext which allows the single customizable context builder to create the GraphQlContext.
This is a good first step.
There are several cases where customers would like to add additional information to the context that can then be referred by instrumentation and other downstream aspects, but unfortunately the custom context builder is a one-shot deal -- and I do not wish to override the way the that context is built in many applications that define their own DgsCustomContextBuilder, instead I'd like to add additional context to the GraphQlContext.
To properly support and leverage the intent of using GraphQLContext as a shared namespace for different pieces of information, an additional contract needs to be made available by customers of DGS to enable them to add/contribute to the context, from potentially different pieces of their framework code, without having to replace/override the single custom context builder, that often I find is defined by the final/consumer of said common frameworks.
Describe Preferred Solution
I propose we add support to DGS to retrieve a set of GraphQLContext contributor classes (Spring Beans implementing a particular interface) that are invoked after the context builder has built the context, but before execution, so that they have the ability to provide additional contextual information (perhaps based on http headers, operationName, variables or extensions of the request) in the GraphQLContext under their own namespace.
This contributor interface should have a method that accepts at least the same information that is passed to the custom context builders (see: DgsCustomContextBuilderWithRequest.build), potentially also including the variables and operationName as well.
Describe Alternatives
None come to mind at this point.
I think this makes a lot of sense based on the new GraphQLContext.
To help design this properly, could you describe some real-world use cases you have in mind that we could also use as test/example cases?
I have one real-world case in hand at the moment, to provide a single way to provide the proper support for federated tracing properly both for projects who define and use their own custom context builder and for those projects that do not (and the default builder is used).
For context, Federated tracing in its instrumentation code is enabled by default if it cannot detect if a specific header was sent on the incoming request. By DGS adding this capability, this would provide one the ability to register a context provider that provides the necessary signal for FederatedTracingInstrumentation by setting apollo-federation-include-trace in the context.
So once this capability exists, we can properly pass the signal to the context by setting apollo-federation-include-trace in the context map to ftv1 if that header was set, or set it to some other value if the header was not present.
Motivation: There is additional overhead caused by performing Federated Tracing, and Apollo studio has made changes so it only sends the header to sub-sample particular requests, but currently there is no way to wire up that connection with the currently available spring and dgs frameworks.
I've created a MR with an initial POC that exercises a very similar pattern to what I described above on how FederatedTracingInstrumentation would need to be signaled based on a header.
Once Im sure I'm somewhere in the neighborhood/adjusted to any feedback or improvements needed, I can figure out how to do the similar actions that need to be done for the reactive version, as well as add a few more tests.
Updated the MR completed the reactive version and added tests around it as well.
Created new implementation in new PR https://github.com/Netflix/dgs-framework/pull/1145 based on Instrumentation per PR feedback by @berngp in initial implementation proposal
https://github.com/Netflix/dgs/pull/106 created to supply corresponding documentation