apollo-feature-requests icon indicating copy to clipboard operation
apollo-feature-requests copied to clipboard

Allow nested Apollo Providers to provide values to merge into operation context

Open adamesque opened this issue 3 years ago • 0 comments

Background

We're using Apollo Client and the React integration across a large collection of codebases powered by webpack module federation. This means that at runtime, on a given page and route, we may dynamically include components that issue GraphQL operations. In the absence of an authoritative/well-enforced operation naming scheme, it can be difficult to understand which operations were issued by which federated component. Ideally, this attribution would be added to each operation's context so that we can extract and process it in a custom Link. We could ask each contributing team to add it manually (and even enforce via custom lint rules, etc), but adding housekeeping details to every operation adds noise to the codebase and can reduce clarity.

Suggested Solution

We do maintain this info in a React context wrapping the federated component boundaries. The most elegant and unobtrusive solution might be if we could wrap our federated components in a provider and supply an object that would be merged with:

  • the value provided by any parent providers
  • the operation context supplied directly at call sites by useQuery, useMutation, etc, and ideally any operations initiated by clients retrieved via useApolloClient.

Values from child contexts should override values from parents, and context supplied at the call site should override all.

It might be easiest to add an optional context prop to ApolloProvider:

// index.js
<ApolloProvider client={client} />
  <App>
    <ApolloProvider client={client} context={{module: 'ComponentA'}}>
      <ComponentA />
    </ApolloProvider>
  </App>
</ApolloProvider>

Supporting this with the main Apollo hooks would be trivially easy, but correctly merging operation context for client instances retrieved from useApolloClient might be tricky. We're currently exploring an approach involving nested ApolloProviders and passing a proxy to the original client with a few key methods overridden, so perhaps returning a proxied client from useApolloClient would work with this solution as well.

adamesque avatar Jul 25 '22 22:07 adamesque