Nested GraphQL query with array argument

I am using apollo-datasource-rest with apollo-server-lambda and trying to figure out how to map a query to a specific resolver. I have the following schema, in which the plan query is supposed to return a list of users (that should be driven by the users query rather than the user query).

  type Query {
    user(user_id: String, username: String): User
    users(user_ids: [String!]): [User!]
    plan(plan_id: String): Plan
  }

  type User {
    id: String
    username: String
    first: String
    last: String
    image: String
  }

  type Plan {
    title: String
    image: String
    attending: [User]
  }

The plan query resolver datasource is as follows:

planReducer(data) {
  return {
    image: data.public.info.image,
    title: data.public.info.title,
    attending: Object.keys(data.public.attending)
  }
}

data.public.attending in the planReducer returns an array of user_ids that I would like to then be able to feed into my users query as opposed to my user query.

These are my current resolvers:

user: (_, { username }, { dataSources }) =>
  dataSources.userData.getUserByUsername({ username: username }),
users: async (_, { user_ids }, { dataSources }) => {
  const usersArray = await dataSources.userData.getUsersByIds({ userIds: user_ids })
  return usersArray
},
plan: async (_, { plan_id }, { dataSources }) => {
  return dataSources.planData.getPlanById({ planId: plan_id })
}

Upvotes: 0

Views: 1041

Answers (1)

j.fong
j.fong

Reputation: 208

Your resolver map should look like below:

const resolvers = {
  Query: {
    plan: async (_parent, { plan_id: planId }, { dataSources }) => (
      dataSources.planData.getPlanById({ planId })
    )
  },
  Plan: {
    users: async ({ user_ids: userIds }, _variables, { dataSources }) => (
      dataSources.userData.getUsersByIds({ userIds })
    )
  }
}

Every key within Query should be a resolver that corresponds to a query defined within the root Query of your schema. Keys that are direct children of the root, in this case Plan, will be used to resolve their corresponding types when returned from the plan resolver within Query.

If resolvers are not defined, GraphQL will fall back to a default resolver which in this case looks like:

const resolvers = {
  Plan: {
    title: (parent) => parent.title,
    image: (parent) => parent.image,
  }
}

By specifying a custom resolver, you are able to compute fields to return to your clients based on the return value of parent resolvers.

Upvotes: 1

Related Questions