GraphQL解析基于"姐妹"字段结果

时间:2018-03-21 15:44:34

标签: graphql apollo

给出一个简单的架构:

type Feed {
  posts:[Post]
  authors:[Author]
}
type Post {
  title:String
  authorId:String
  author:Author
}
type Author {
  id:String
  name:String
  ...
}

消费应用可以继续以两种不同的方式请求发布帖子及其作者: 1)"正常"列出作者的方式:

Feed { posts { title, author { name } } }

2)这样一种方式可以让应用程序自己编写作者索引,从而限制响应体大小(因为只有唯一作者才会回复他们的详细信息)。

Feed { posts { title, authorId } authors {id, name} } 

然而,这在解析查询/作者方面存在问题,因为所需作者ID的列表仅在解析帖子后才知道,因此需要作者的决心等待直到帖子被解析。

简而言之:一个领域需要能够等待解决一个姐姐"领域,在能够自我解决之前。

这样做的一种方法是创建一个事件发射器,通过请求上下文共享。然而,这确实可以解决问题...... 我想知道是否有更好/更优雅的解决方案?

仅供参考:上面的例子是简化的,在我的用例中,有多个字段与"实体"保持关系,这使得"索引方法"效率更高。

type RelationType1 { entityId }
type RelationType2 { entityId, owningEntityId }
type RelationType3 { entityId, owningEntityId, representedEntityId }
type Item { rel1:[RelationType1], rel2:[RelationType2], rel3:[RelationType3] ... }
...

1 个答案:

答案 0 :(得分:0)

您可以做的是将实施向上移动到Feed的解析器中:

type FeedRecord = {
  postId: string,
}

type PostRecord = {
  id: string,
  authorId: string,
  // ...
}

async function feed({ userId }, args, { loaders }) {
  const feeds: FeedRecord[] = await loaders.FeedByUserIdLoader.load(userId);
  const posts: PostRecord[] = await loaders.PostByIdLoader.loadMany(
    feed.map(feed => feed.postId)
  );

  return {
    posts,
    authorIds: posts.map(post => authorId)
  }
}

现在整个Feed字段只会在帖子已加载时解析。在这种情况下,你不会做额外的工作,因为你需要帖子来解决作者无论如何,如果没有要求作者,地图功能并不昂贵。如果您的Feed类型中有更多字段(例如hasUpdates),那么查询帖子和作者都不会有问题,您可能需要使用第四个解析器参数 resolveInfo 来检查是否需要做查找。