GraphQL 流式传输类型?

Posted

技术标签:

【中文标题】GraphQL 流式传输类型?【英文标题】:GraphQL streaming type? 【发布时间】:2015-11-16 14:36:55 【问题描述】:

我现在正在使用GraphQL-JS,将其连接到 MariaDB 后端。

我已经弄清楚如何返回整个结果集:

const queryType = new GraphQLObjectType(
    name: 'Query',
    fields: () => (
        users: 
            type: new GraphQLList(userType),
            resolve: (root, args) => new Promise((resolve, reject) => 
                db.query('select * from users', (err, rows, fields) => 
                    if(err) return reject(err);
                    resolve(rows);
                );
            ),
        
    )
);

这很酷,但 library I'm using 也让我 stream results 逐行。

GraphQL 有什么可以促进这一点吗?

据我所知,GraphQLList 期待一个完整的数组,我只能解析我的结果集一次,不能使用 Emitter 或其他东西进行馈送。

【问题讨论】:

【参考方案1】:

(这不是一个完整的答案,但也不适合评论)

根据 graphQL 规范。应该可以的:

GraphQL 提供了许多内置的标量,但 类型系统可以 添加具有语义含义的附加标量。例如,一个 GraphQL 系统可以定义一个称为 Time 的标量,它虽然被序列化为 字符串,承诺符合 ISO-8601。查询类型字段时 时间,然后您可以依靠解析结果的能力 ISO-8601 解析器并使用特定于客户端的原语来表示时间。其他 一个可能有用的自定义标量的例子是 Url,它序列化 作为一个字符串,但服务器保证它是一个有效的 URL。

所以结构应该是这样的:

var myStream = new GraphQLScalarType(
    name: "myStream",
    serialize: ...
    parseValue: ...
    parseLiteral: ...
  );

现在我猜你可以尝试返回 promises/streams 看看会发生什么,但我认为它还不被支持。很多人都在问这个问题,我想我看到了来自 graphQL 团队的某个人的评论,说他们正在调查这个问题(很遗憾找不到它)。

个人意见,但如果不将这种行为纳入 graphQL 的核心就无法更改,则可能表明现在的 graphQL 不够灵活。

【讨论】:

【参考方案2】:

无法使用基本 GraphQL 服务器流式传输结果,因为它具有客户端-服务器架构(您发送 HTTP 请求并返回 HTTP 响应)。

不过,订阅是可能的。他们是 GraphQL 的 recently added(请参阅 the story behind)。

【讨论】:

我想当我写这篇文章时,我希望resolve 允许生成器返回类型或其他一些流。在生成器/流耗尽/关闭之前,不会发送 HTTP 响应。我会查看您发布的这些链接。流式响应会更酷,但可能更难处理。【参考方案3】:

请参阅 GraphQL @stream 指令,例如 https://github.com/rmosolgo/graphql-ruby-stream-defer-demo

【讨论】:

以上是关于GraphQL 流式传输类型?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Node 和 graphql 将文件流式上传到 Azure Blob 存储

GraphQL 是不是消除了数据传输对象?

数组中类型为 graphql 对象的 GraphQL 字段

Graphql 工具:将实体类型映射到 graphql 类型

错误:使用 Nestjs + Graphql + Typeorm 时无法确定 GraphQL 输入类型

OrchardCore 中为现有类型 实现自定义 Graphql 查询