Apollo-server: Context and Nested Resolvers - Nested Mutations

Created on 25 Dec 2019  路  3Comments  路  Source: apollographql/apollo-server

Hi. While I was using nested mutations as mentioned here: https://github.com/graphql/graphql-js/issues/221#issuecomment-568894704 I noticed a strange behavior with the resolvers in Apollo Server.

The context object of the parent mutation resolver is being passed as the arg of the child resolver.

Description below. Is it intended? Can I go ahead and use it from args? Or will this behavior be changed?

export const parentResolver = (parent, args, context, info) => {
    console.log('args:', args);
   // CONTEXT COMES UP CORRECTLY
    console.log('context:', context);

    return {
        createChannels: async (parent1, args1, context1, info1) => {
    // CONTEXT IS UNDEFINED HERE
    console.log('context:', context1);
    // CONTEXT OF THE PARENT IS BEING PASSED ONTO ARGS OF CHILD
    console.log('args:', args1);
   }
};

Not just this, parent1 gets args of parent resolver, args1 get context of parent resolver. Looks like there are only 3 arguments for child resolver function.

Thanks in advance.

Most helpful comment

@tvvignesh I've found that when I name my mutations the following way, namespacing and organization "just kinda happens":

<primaryResource><Action><SecondaryResource>

e.g.

type Mutation {
  userCreate
  userAddContactInformation
  userAddFriend
  userAddGroup
  userGroupDelete # "userGroup" is a more complex resource. "group" is what it would normally be called in the context of the users service, but "userGroup" is globally-aware
  userRemoveGroup
  usersCreate # the one from your example
}

Normally, I would also alphabetize these. As long as everyone understands what the verbs should be (e.g. when to use "create" vs "add"), that's not usually a problem.

All 3 comments

@tvvignesh I think you missed something important in that thread:

We do not support mutations at any level other than the top

Resolvers are supposed to return values, not functions. I believe what you're trying to do is below. As you can see, they're not actually called within context of each other.

const resolvers = {
  Mutation: {
    User(parent, args, context) => {
      // I really hope you don't do this, but you *could*
      return something;
    },
  },
  UserOps: {
    createUsers(parent, args, context) {
        // do whatever
        return stuff;
    }
  }
}

Be aware, though, it's not really supported, and you're not really making a "nested mutation". According to the GraphQL Spec, you're making a Mutation without arguments. Then you're asking for the response, and you're modifying data in your datastore based on query parameters you're passing to your response filter.

@dncrews Thanks a lot for your suggestion. Had issues when I nested createUsers within UserOps in Apollo. The context was not getting passed and also there was a mismatch in arguments. Ended up removing everything and moved all mutations to Root.

While I understand nesting them is not supported officially, I am not sure how to group them in such a way that users can find the mutations easily from the GraphiQL explorer.

@leebyron Sorry for bringing you to this thread, but any thoughts on how we can group graphql mutations? I am already seeing so many mutations in my code.

Maybe an option to TAG mutations or schema with key value pairs? It can help people in filtering things out easily,

@tvvignesh I've found that when I name my mutations the following way, namespacing and organization "just kinda happens":

<primaryResource><Action><SecondaryResource>

e.g.

type Mutation {
  userCreate
  userAddContactInformation
  userAddFriend
  userAddGroup
  userGroupDelete # "userGroup" is a more complex resource. "group" is what it would normally be called in the context of the users service, but "userGroup" is globally-aware
  userRemoveGroup
  usersCreate # the one from your example
}

Normally, I would also alphabetize these. As long as everyone understands what the verbs should be (e.g. when to use "create" vs "add"), that's not usually a problem.

Was this page helpful?
0 / 5 - 0 ratings