【问题标题】:GraphQL resolving based on "sister" fields results基于“姐妹”字段结果的 GraphQL 解析
【发布时间】:2018-03-22 06:34:22
【问题描述】:

给定一个简单的架构:

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] ... }
...

【问题讨论】:

    标签: graphql apollo


    【解决方案1】:

    您可以做的是将实现上移一级到提要的解析器中:

    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)
      }
    }
    

    现在整个提要字段只有在帖子已经加载时才会解析。在这种情况下,您不会做额外的工作,因为无论如何您都需要帖子来解决作者的问题,并且如果不请求作者,则地图功能并不昂贵。当您的提要类型上有更多字段(例如 hasUpdates)以便既不查询帖子也不查询作者时,此解析器可能会出现问题,您可能希望使用第四个解析器参数 resolveInfo 来检查是否需要进行查找。

    【讨论】:

    • 我明白你在解释什么,这是一个有效的选择。在这两种情况下,确实需要检查 resolveInfo 以保持其性能。 (如果不在查询中,则无需在根目录加载作者)。两种方法之间的主要区别在于结果的加载位置。在您的示例中,根查询进行解析,而在事件发射器中,解析保留在字段内。事件发射器确实单独关注(加载帖子的位置)更好一点,并限制作者的数据库请求(尽管这可以使用数据加载器来解决)
    • 实际上,现在我考虑一下,您也可以在作者字段的解析器中解析帖子。如果您使用 Dataloader,则不会做额外的工作。我只是认为“不纯”的解析器很难推理。如果我应该采用该代码,或者您是否理解我的意思,请告诉我。
    • @Herku 我知道已经 3 年了,但你能帮忙写一些代码吗?
    猜你喜欢
    • 2017-11-09
    • 2013-02-12
    • 2017-02-25
    • 1970-01-01
    • 2020-10-07
    • 2014-03-04
    • 2019-08-29
    • 2019-10-03
    • 1970-01-01
    相关资源
    最近更新 更多