javascriptgraphqlapolloapollo-server

Modifying the context value in GraphQL resolvers


The Apollo Server docs state:

Resolvers should never destructively modify the contextValue argument. This ensures consistency across all resolvers and prevents unexpected errors.

I'd like some help unpacking this statement.

  1. "Never destructively modify" I guess means that you can add properties to the context, but not remove or mutate them?
  2. "Ensures consistency across all resolvers" I guess refers to situations where query resolvers are processed in parallel such that a context value could change unexpectedly mid-execution. But what about mutation resolvers which are processed in series – would it be safe to mutate the context in that case?

My issue is this:

  1. I load the authenticated user as part of the context initialisation function.
  2. I put the user object into the context to be used by resolvers.
  3. I have a setUserDetails mutation which can update the user.
  4. If I run a query with two mutations (e.g. setUserDetails followed by sendWelcomeEmail), the second mutation sees the original user details, not the updated ones unless I mutate the context.

This leads to "unexpected errors" which was the thing we were trying to avoid in the first place.

So my question is: is it OK to mutate the context in a mutation resolver? Or is there another recommended approach to avoid this issue?


Solution

  • You seem to be quite aware of the issues that can originate from mutating the context value. I think the intention of the docs is to prevent people from using the context to pass around values. I think, ideally the context is created once and then never modified.

    I think in your case, your context also somewhat serves as a cache (which is not uncommon), so I think it should be fine to invalidate or update cache entries after an update.

    Nevertheless, I would consider the following: