帮酷LOGO
  • 显示原文与译文双语对照的内容
A GraphQL batching model which groups execution by GraphQL fields.

  • 源代码名称:graphql-resolve-batch
  • 源代码网址:http://www.github.com/calebmer/graphql-resolve-batch
  • graphql-resolve-batch源代码文档
  • graphql-resolve-batch源代码下载
  • Git URL:
    git://www.github.com/calebmer/graphql-resolve-batch.git
  • Git Clone代码到本地:
    git clone http://www.github.com/calebmer/graphql-resolve-batch
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/calebmer/graphql-resolve-batch
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
  • GraphQL批处理解析器

    batching resoluition/GraphQL 和 graphql-tools 一起处理字段的的一种方法。

    import { GraphQLObjectType, GraphQLString } from'graphql';import { createBatchResolver } from'graphql-resolve-batch';constUserType=newGraphQLObjectType({
     //.. .});constQueryType=newGraphQLObjectType({
     name:'Query',
     fields: {
     user: {
     type: UserType,
     resolve:createBatchResolver(async (sources, args, context) => {
     const { db } = context;
     constusers=awaitdb.loadUsersByIds(sources.map(({ id }) => id));
     return users;
     }),
     },
     },
    });

    有关使用 GraphQL.js 插件和graphql-tools 插件的完整示例,请确保查看./examples 目录

    安装

    graphql-resolve-batchgraphql 有对等依赖关系,所以请确保你已经安装了该软件包。

    npm install --save graphql graphql-resolve-batch

    为什么?

    GraphQL是面向前端和后端开发人员的强大数据查询语言。 但是,由于如何执行GraphQL查询,很难定义高效的GraphQL模式。 例如下面的查询:

    {
     users(limit: 5) {
     namefriends(limit: 5) {
     name }
     }
    }

    这说明了GraphQL选择任意嵌套数据的能力。 然而从开发人员的架构角度优化 Pattern 是一个困难的方法。

    Select the first 5 users.
    Select the first 5 friends for the first user.
    Select the first 5 friends for the second user.
    Select the first 5 friends for the third user.
    Select the first 5 friends for the fourth user.
    Select the first 5 friends for the fifth user.

    我们有N+1问题 ! 对于我们正在执行数据库查询的每个用户。 这is效率不高而且没有规模。 当我们拥有:

    {
     users(limit: 5) {
     namefriends(limit: 5) {
     namefriends(limit: 5) {
     namefriends(limit: 5) {
     name }
     }
     }
     }
    }

    这变成了 156个查询 !

    解决这个问题的标准解决方案是使用 dataloader,它被认为实现了Facebook用来在JavaScript中优化他们的GraphQL API的一个 Pattern 。 dataloader 对于具有简单键的批查询非常出色。 例如这里查询:

    {
     users(limit: 5) {
     namebestFriend {
     name }
     }
    }

    因为的值是一个标量,所以使用 dataloader 查询这个GraphQL查询很容易。 实例的简单字符串标识符。 但是,当我们将参数添加到公式中时:

    {
     users(limit: 5) {
     namefriends1: friends(limit: 5) {
     name }
     friends2: friends(limit: 5, offset: 5) {
     name }
     }
    }

    突然间,这些键并不是简单的标量。 如果我们想使用 dataloader,我们可能需要使用两个实例。 一个用于 friends(limit: 5),一个用于 friends(limit: 5, offset: 5) 然后在每个实例上我们可以使用一个简单的键。 这样的实现可以能非常快速地变得非常复杂,并且可以能不是你想要花费时间的。

    这个包提供了 dataloader 批处理策略的替代方案。 这个软件包实现了一个opinionated的批处理策略,为GraphQL定制。 这个包不是使用简单的密钥进行批处理,而是通过 GraphQL字段批处理。 例如让我们再次查看下面的查询:

    {
     users(limit: 5) {
     namefriends(limit: 5) { # Batches 5 executions.namefriends(limit: 5) { # Batches 25 executions.namefriends(limit: 5) { # Batches 125 executions.name }
     }
     }
     }
    }

    在这里,我们只会有的执行,而不是 156. 一个用于 root 字段,一个用于第一个 friends 字段,一个用于第二个 friends 字段,依此类推。 这是 dataloader的强大替代方案,在这种情况下 dataloader 很短。

    批处理冲突解决程序将在每个 GraphQL 字段运行一次。 所以假如我们假设你在 friends 域使用批处理解析器,前端工程师就会像这样写一个查询:

    {
     users(limit: 5) {
     namefriends(limit: 5) {
     namefriends(limit: 5) {
     namefriends(limit: 5) {
     name }
     }
     }
     }
    }

    每个 friends(limit: 5) 字段只运行一次。 这里操作如何工作GraphQL.js 解析程序具有以下签名:?

    (source, args, context, info) => fieldValue

    To通过字段 batch resolution graphql-resolve-batchsource defers resolution batch batch batch batch batch 。 在下一个刻度中,你传入 createBatchResolver的函数被调用在最后一个记号中bucketed的所有源。

    实现与 dataloader 实现非常类似。 除了 graphql-resolve-batch 对如何在GraphQL中实现批处理采用了更为简单的方法外,而 dataloader 在如何将执行合并到一起。

    要查看如何使用批处理解析器优化 above 查询,请确保查看 GraphQL.js 示例

    我什么时候使用 dataloader,什么时候使用 graphql-resolve-batch

    如果你对以下任一问题回答是:

    • 你是否有一个简单的原语键,如字符串或者数字,可以用来处理?
    • 是否要在整个架构中对请求进行批处理?
    • 是否要使用相同的密钥缓存数据,以便它不需要被请求?

    使用 dataloader 。但是对于 dataloader 很有用的所有情况,graphql-resolve-batch 也很有用。 如果你发现 dataloader 是复杂的,而且它的优点不是很有吸引力,你可以以在任何地方使用 graphql-resolve-batch

    但是,如果你对以下任一问题回答是:

    • 你的字段是否有参数?
    • 从源值的源值中导出原始值是很困难的?
    • 你不具备向 context 添加任何新值的能力? ( 例如在嵌入式GraphQL架构中)

    你几乎肯定想使用 graphql-resolve-batch 。 如果你使用 dataloader,那么 graphql-resolve-batch 在几个小例子中只会更好。 但是,graphql-resolve-batch 更容易设置。

    Credits

    享受高效的GraphQL api跟随作者,@calebmer 在 Twitter 上获得更出色的工作。




    Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语