4
votes

So what I'm trying to do its to make a GraphQL like this if possible:

{
  people {
    _id
    name
    acted {
      _id
      title
      coactors {
        name
      }
    }
  }
}

So what I'm doing, it's getting actors (people), then get the movies they acted, that works fine. So then I'm trying to get the co-actors in that movie. I'm thinking to pass the current actor's id to the co-actors field as an argument like this:

{
  people {
    _id
    name
    acted {
      _id
      title
      coactors(actor: people._id) {
        name
      }
    }
  }
}

Obviously, I'm getting an error and don't know if that could be made internally.

So here are my Types:

const MovieType = new GraphQLObjectType({
    name: 'movie',
    fields: () => ({
        _id: {
            type: GraphQLInt
        },
        title: {
            type: GraphQLString
        },
        tagline: {
            type: GraphQLString
        },
        released: {
            type: GraphQLInt
        },
        actors: {
            type: new GraphQLList(PersonType),
            resolve: (movie) => {
                return [];
            }
        },
        coactors: {
            type: new GraphQLList(PersonType),
            args: {
                actor: {
                    type: GraphQLInt
                }
            },
            resolve: (movie, args) => {
                getCoActorsFor(movie, args.actor) // How can I do something like this
                    .then((actors) => {
                        return actors;
                    })
            }
        }
    })
});

const PersonType = new GraphQLObjectType({
    name: 'person',
    fields: ()=> ({
        _id: {
            type: GraphQLInt
        },
        name: {
            type: GraphQLString
        },
        born: {
            type: GraphQLInt
        },
        acted: {
            type: new GraphQLList(MovieType),
            resolve: (person) => {

                return [];

            }
        }
    })
});
1

1 Answers

5
votes

This isn't possible without breaking the query into two queries, so you have the results of the first to supply as variables for the actor to supply to the second.

Instead of using variables, you could have the movies objects returned by "acted" to include a reference to the actor such than when you ask for "coactors" that you have that information at hand to do what you're trying to do.

However this type of API is also an anti pattern - if a subobject relies on context from a parent object then it is much more difficult to cache and understand. I think you should ask yourself why a Movie object must return coactors in addition to actors. If coactors are just the same list of actors but with the original actor removed, that seems like something which could easily happen on the client where that contextual information is far more readily available.