1

What would the best approach to fetch deep nested object with graphql only when asked for. I'm talking here performance wise

Lets say you have the following mongo/mongoose schema :

User 
  |
  |_ Name
  |
  |_ Friends (RefId into User)
      |
      |_ User
          |
          |_ Friends (RefId into User)

      .....

suppose each user has many friends who in turn have many other friends, how would decide how deeply you need to populate inside a resolve function?

the naive method of "just populating" might be harmful as many of the queries might just select the field name which is on the 0 level, but end up populating 1/2 of your db.

Thanks in advance.

Pavel 'PK' Kaminsky
  • 796
  • 1
  • 10
  • 22
  • 1
    Why not just return the users found within the parent user's Friends field? Are you specifically trying to eagerly load friends of friends to a specific depth? If so, you need to be wary of friends of friends that are already friends of other friends so you don't have an infinite loop. – Brendan Turner Mar 31 '16 at 15:25
  • @BrendanTurner the point i try to make here is not the "cyclic loops" but rather how do we dynamically decide how deep should we populate.. if it help you can image the example with user who has friends who have a jobs field. now some of the queries will need to populate 3-rd level nesting , but some will just grab the name. – Pavel 'PK' Kaminsky Mar 31 '16 at 16:26
  • Right, so specify that in the query. Here's a gist that should help clarify: https://gist.github.com/xpepermint/7376b8c67caa926e19d2 – Brendan Turner Mar 31 '16 at 16:30

1 Answers1

1

The best way will be to have the GraphQL client specify how deeply nested data it wants, i.e., having the client pass a parameter when it asks for friends of a user.

Using graphql npm package, the implementation looks like below:

const UserType = new GraphQLObjectType({
  name: 'NestedUser',
  fields: {
    ...
    ...
    friends: {
      type: new GraphQLList(UserType),
      args: {
        level: {
          type: GraphQLInt,
          defaultValue: 0,
        },
        ...connectionArgs,
      },
      resolve: (user, {level, ...args}) => {
        // Populate nestedFriends according to the level
        return nestedFriends;
      },
    },
  },
});
Ahmad Ferdous
  • 3,351
  • 16
  • 33
  • that's and interesting approach, thanks. I wonder if we can manipulate the mongo query according to the fields without explicitly mentioning the depth – Pavel 'PK' Kaminsky Apr 13 '16 at 14:06