【问题标题】:GraphQL server side streaming implementationGraphQL 服务器端流式实现
【发布时间】:2020-02-08 06:05:00
【问题描述】:

因此,在过去,我能够创建一个 REST 端点并使其能够流式传输大文件。我使用 Java 和 Jersey(REST 库)来做到这一点。我可以创建一个类似于下面代码的端点——客户端可以点击它,服务器会在不使用大量内存的情况下输出大文件,客户端会立即开始下载文件。

@GET
@Path("/getFile")
public Response getFile(){
    InputStream file = getFileStreamFromDB();
    Response response = Response.ok().entity(stream);

    return response;
}

现在我正试图弄清楚如何使用 GraphQL 应用类似的模式。用例有点不同 - 现在我从数据库而不是文件中提取大型结果集。我有一个用 Kotlin 和 KGraphQL 构建的 GraphQL 服务器。从我所做的研究来看,我似乎需要发送整个对象作为对 GraphQL 调用的响应。

我的用例是在基于 React 的仪表板上显示数据。在某些情况下,我们有大量数据,可能需要一些时间才能将响应发送到客户端,因为必须发送整个结果集。我希望将数据流式传输到仪表板中,以便用户可以立即开始查看一些数据,而不是等待 15 或 20 秒才能显示。

GraphQL 解析器可以是某种对象或字符串:

query("returnString"){
    resolver { -> "this is a string"}
}

但是,如果我尝试返回如下所示的 InputStream:

query("returnStream"){
    resolver { -> ({
            val stream = ByteArrayInputStream("this is a string".toByteArray(Charsets.UTF_8))
            stream
        })
    }
}

尝试启动 GraphQL 服务器时出现以下异常:

原因:com.apurebase.kgraphql.schema.SchemaException: Generic GraphQL 不支持类型,找到 () -> java.io.ByteArrayInputStream 在 com.apurebase.kgraphql.schema.structure2.SchemaCompilation.handlePossiblyWrappedType(SchemaCompilation.kt:147) 在 com.apurebase.kgraphql.schema.structure2.SchemaCompilation.handleOperation(SchemaCompilation.kt:131) 在 com.apurebase.kgraphql.schema.structure2.SchemaCompilation.handleQueries(SchemaCompilation.kt:112) 在 com.apurebase.kgraphql.schema.structure2.SchemaCompilation.perform(SchemaCompilation.kt:55) 在 com.apurebase.kgraphql.schema.dsl.SchemaBuilder.build(SchemaBuilder.kt:26) 在 com.apurebase.kgraphql.KGraphQL$Companion.schema(KGraphQL.kt:8)

我们在前端使用 apollo,所以我觉得我们可以在客户端利用流指令 - 我只是不确定如何设计 GraphQL 解析器来返回流。

有没有一种方法可以流式传输对 GraphQL 调用的响应?还是我目前必须为此使用 REST?

【问题讨论】:

  • 这是因为 ByteArrayInputStream 有一个 byteArray 字段,并且 KGraphQL github issue#55 目前不支持 java 数组。
  • 除此之外,这只是试图返回 ByteArrayInputStream 对象,而不是实际将数据流回,因此您目前无法通过 KGraphQL 完成您想要实现的目标。

标签: kotlin graphql


【解决方案1】:

与流响应最接近的 GraphQL 等价物可能是订阅:https://graphql.org/blog/subscriptions-in-graphql-and-relay/。将您正在做的事情作为对 DB 行“事件”的订阅来实现对我来说似乎是合理的。

KGraphQL 目前似乎没有实现这一点:https://github.com/aPureBase/KGraphQL/issues/10

不过,graphql-kotlin 项目 (https://github.com/ExpediaGroup/graphql-kotlin) 在 spring-boot 基础上实现了订阅:https://expediagroup.github.io/graphql-kotlin/docs/server/subscriptions

如果您习惯了球衣并且更愿意坚持使用它,我们将利用 graphql-kotlin 的基础库组合一个单独的实现来在 dropwizard(球衣等)基础上实现订阅:https://github.com/trib3/leakycauldron/tree/master/graphql

【讨论】:

    猜你喜欢
    • 2017-06-25
    • 2021-05-14
    • 2020-07-31
    • 2018-05-19
    • 2017-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 2021-12-12
    相关资源
    最近更新 更多