GraphQL,Dataloader,[ORM or not],具有许多关系理解

时间:2018-09-04 11:38:51

标签: orm sequelize.js graphql graphql-js apollo-server

我第一次使用Facebook的数据加载器(https://github.com/facebook/dataloader)。

我不了解当我与许多人有1对多的关系时如何使用它。

这是我的问题的重制:https://enshrined-hydrant.glitch.me

如果您在操场上使用此查询:

query {
  persons {
    name
    bestFriend {
      name
    }
    opponents {
      name
    }
  }
}

您可以获得价值。

但是,如果您在此处打开控制台日志:https://glitch.com/edit/#!/enshrined-hydrant,则可以看到这些我想避免的数据库调用:

enter image description here

我的人员类型是:

type Person {
  id: ID!
  name: String!
  bestFriend: Person
  opponents: [Person]
}

我可以使用适合bestFriend: Person的数据加载器,但我不知道如何与opponents: [Person]一起使用它。

如您所见,解析器必须返回一个值数组

您对此有任何暗示吗?

1 个答案:

答案 0 :(得分:0)

您需要创建批处理的端点才能与数据加载器一起使用-它不能单独进行批处理。

例如,您可能需要以下端点:

GET /persons - returns all people
POST /bestFriends, Array<personId>` - returns an array of best friends matchin the corresponding array of `personId`s

然后,您的数据加载器可能如下所示:

function batchedBestFriends(personIds) {
  return fetch('/bestFriends', {
    method: 'POST',
    body: JSON.stringify(personIds))
  }).then(response => response.json());
  // We assume above that the API returns a straight array of the data.
  // If the data was keyed, you could add another accessor such as
  // .then(data => data.bestFriends)
}

// The `keys` here will just be the accumulated list of `personId`s from the `load` call in the resolver
const bestFriendLoader = new DataLoader(keys => batchedBestFriends(keys));

现在,您的解析器将类似于:

const PersonType = new GraphQLObjectType({
  ...
  bestFriend: {
    type: BestFriendType,
    resolve: (person, args, context) => {
      return bestFriendLoader.load(person.id);
    }
  }
});