【发布时间】: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 完成您想要实现的目标。