简体   繁体   中英

How to create a GraphQL resolver that can ‘complete’ a type

Let's say we have a mutation that returns an array of objects with only the property id . To “complete” this type we have to create a resolver for every single property of this object.

Instead I'd like to be able to create a resolver that can complete an object.

Below an example of a query that sends a list of heroes and a mutation to favorite one. The resolver of the mutation setFavorite(id) returns only a list of IDs .

type Query {
  heroes(first: Int = 10) [Hero]
}

type Hero {
  id: ID!
  title: String!
}

type Mutation {
  setFavorite(id: ID!): [Hero]
}
const resolvers = {
  Query: {
    heroes(_, {first}, {heroes}) {
      return heroes.get({first});
    }
  },
  Mutation: {
    setFavorite(_, {id}, {favorites}) {
      await favorites.setFavorite(id);
      return favorites.getAll(); // <<<< these are only IDs
    }
  }
}

Is it possible to create a resolver, that "completes" a type?

const resolvers = {
  Hero: {
//  vvvvvv something like this
    __type(parent, _, {heroes}) {
      if (parent.id) {
        return heroes.getOne({id: parent.id});
      }
    }
  }
}

Only fields are resolved , so you can only write resolvers for fields, not types. Your options are:

  • Change methods like getAll to actually return instances of the models in question instead of just returning the IDs.

  • Map the returned IDs to model instances inside each resolver.

  • Write a resolver for each child field:

const resolvers = {
  Hero: {
    title: (id, args, ctx) => {
      const hero = await ctx.dataloaders.hero.findById(id)
      return hero.title
    },
    someOtherField: (id, args, ctx) => {
      const hero = await ctx.dataloaders.hero.findById(id)
      return hero.someOtherField
    },
  },
}

Notice that we use dataloader in this example. This lets us batch the calls to findById and avoids calling the method twice for the same id. You shouldn't use this pattern without DataLoader; otherwise you'll end up with unnecessary additional calls to your database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM