【问题标题】:File uploading with Relay Modern & GraphQL使用 Relay Modern 和 GraphQL 上传文件
【发布时间】:2018-06-27 22:31:01
【问题描述】:

所以我已经研究了两天,对 Java 的了解还不够,无法完全实现解决这个问题的方法。在客户端,我找到了一些 excellent user documentation 并相信我有正确的部分,但是在处理服务器中的入站 multipart/formdata 时,我有点迷茫。

我的应用程序的基础是基于 HowToGraphQL Java 教程,因为我觉得他们在组织代码库方面做得很好,并且使事情变得非常简单易懂。不幸的是,文件上传不是他们涵盖的领域,并且每个 graphql-java 包的维护者,no plans exist to directly support this feature。

但这并不是说这是不可能的。 GraphQL 规范旨在成为指导方针,社区如何选择调用规范取决于他们。许多人成功地整合了文件上传,尽管通常是通过包含custom middleware

不幸的是,我的障碍可能只是缺乏领域知识。我主要使用 JavaScript 和 Python 工作,并且主要有 Java 的学术经验。不完全确定从哪里开始,但我想我需要追踪我认为绑定到 SimpleGraphQLServlet 类的响应对象,并找到一种方法来提取入站文件对象。

希望能获得更多专家建议或帮助以提出解决方案。我还没有在 SO 上找到任何基于 Java 的可靠 sn-ps 来解决这个问题,因此解决这个问题可能会使其他尝试采用这个平台的人受益。

编辑:

可能找到了一种方法来做到这一点,但还没有弄清楚具体细节。在扩展 SimpleGraphQLServlet 类的 GraphQLEndpoint 类中,我们公开了 doPost() 方法。然而,提取数据最终会导致一系列错误,第一个错误是通过 @MultipartConfig 注释解决的,但是下一个错误让我再次停滞不前。 “缺少 MultiPart 请求的内容。”

这个doPost()方法似乎是在突变发生后调用的,所以即使我设法提取了文件数据,似乎数据也会放错地方。此外,我想知道丢失的内容是否是 Mutation 消耗帖子数据的结果,假设它甚至到达了。

但是,所有其他参数都完好无损,因此只需访问此文件即可。

【问题讨论】:

    标签: java graphql multipartform-data graphql-java relaymodern


    【解决方案1】:

    关于 HowToGraphQL 的 Java 教程令人遗憾地过时了。我正在努力更新它(我是原版的作者),但这需要时间。 当前的最佳实践是在以模式优先的方式工作时直接使用 graphql-java 的RuntimeWiring*。这里有一些基本文档:http://graphql-java.readthedocs.io/en/v6/schema.html

    无论如何,处理文件上传的方式并没有改变:将整个 HttpServletRequestobject 或只是二进制部分粘贴到共享上下文中:

    graphQL.execute(ExecutionInput.newExecutionInput()
        .query(operation)
        .context(request.getPart("file")) //add the binary to the context
        .build());
    

    稍后,在DataFetcher,您可以通过以下方式获取它:DataFetchingEnvironment#getContext:

    Part file = environment.getContext();
    file.getInputStream(); //do something with the binary content
    

    当然,您可以使用其他(动态)结构作为上下文,而不是直接使用二进制。

    这种处理上传的侧载方式是使用 JSON 作为传输格式的结果,而 JSON 是文本的。与通常在 GraphQL 之外处理文件下载的原因相同(其中响应仅包含 ID 或启动下载所需的 URL)。参考服务器实现包括使用相同策略的示例。
    目前,据我所知,没有非 JSON GraphQL 客户端。

    *对于代码优先,graphql-spqr(我的项目)仍然是最方便的方式。

    【讨论】:

    • 哦,嘿@kaqqao!感谢您如此彻底的回复。实际上,我已经通过 Twitter 与您联系过,因为我希望能提出一个适合您已经建立的基础的解决方案。感谢您将该教程放在一起,它可能已经过时,但只需进行一些小调整,它仍然可以很好地工作。
    • @ScotMatson 很高兴为您服务 :) 抱歉,如果我错过了您在 Twitter 上的消息:/ 不是故意的。而对于文件上传的情况,真的没有更好的办法了……我认为graphql-java-tools可以让你将共享上下文对象注入到方法中,所以同样的策略应该是可以使用的。
    【解决方案2】:

    目前,不幸的是,对我有用的解决方案并未完全遵循我认为的最佳实践,即使用可上传文件、作为多部分/表单数据发送,然后在服务器上注入中间件。但是我能够传输文件数据,所以这是一个足够好的开始。

    最终我选择将我上传的文件编码为 base64,然后通过 GraphQL 突变将数据作为 String 类型发送,然后在收到后我能够解码 base64 字符串。

    目前我看到的只是正在传输的文件内容,而不是元数据。由于某些元数据对我很有价值,因此要么需要与 base64 字符串一起发送,要么可能我只是忽略了这个元素并且它确实存在。

    无论哪种方式,我都会留下一些我在解决这个问题时发现有用的资源,如果其他人遇到这个问题,它可能会很有用。我不认为我当前的解决方案是真正的答案,所以也许随着这些包的发展,我们会看到更好的方法来通过 Relay/graphql-java 上传文件。

    How to convert file to base64 in JavaScript?

    Decode Base64 data in Java

    【讨论】:

      猜你喜欢
      • 2017-03-25
      • 2017-12-30
      • 2017-10-15
      • 2017-12-27
      • 2018-02-12
      • 2018-02-18
      • 2017-10-18
      • 2017-12-12
      • 2018-05-17
      相关资源
      最近更新 更多