GraphQL,如何返回字节[]的类型

Posted

技术标签:

【中文标题】GraphQL,如何返回字节[]的类型【英文标题】:GraphQL, how to return type of byte[] 【发布时间】:2019-03-18 02:33:24 【问题描述】:

我在我的数据库中以字节数组的形式保存了缩略图。我似乎无法锻炼如何通过 GraphQL 将这些返回给前端客户端。

在标准 REST 方法中,我只需将 POJO 与字节一起发送回来,我就可以轻松地将其渲染出来。

但是尝试返回 byte[] 会抛出

无法将类型定义 (ListTypetype=NonNullTypetype=TypeNamename='Byte') 与 java 类型 (class java.lang.Byte) 匹配:Java 类不是 List 或泛型类型信息丢失:类 java.lang.Byte

错误是描述性的,告诉我出了什么问题,但我不知道如何解决。

我的thumbnail.graphqls 看起来像:

type Thumbnail 
    id: ID!
    resource: [Byte!]

还有缩略图 POJO

public class Thumbnail extends BaseEntity 
    byte[] resource;

我在 Java 端使用 graphql-spring-boot-starter 来处理事情,我认为它支持 Byte 开箱即用,那么我哪里出错了?

对 GraphQL 非常陌生,所以这可能只是一个明显的错误。

干杯,

【问题讨论】:

我认为您的问题是您尝试将二进制数组序列化为 json(我猜您从控制器返回 json)。您认为您的回复应该是什么样子? 我希望 GraphQL 的结果看起来与 REST 请求的结果相同。如此有效地,byte[] 看起来像一串字节......这就是我如何让 GraphQL 接受这是一个有效的响应类型? 【参考方案1】:

您必须将其序列化为标准类型之一。 如果你想让你的字节数组看起来像一个字符串,比如“F3269AB2”,或者像一个整数数组,比如 [1,2,3,4,5],这完全取决于你。

您可以通过为您的实体编写解析器来实现序列化,如下所示:

public class ThumbnailResolver extends GraphQLResolver<Thumbnail> 
        public String resource(Thumbnail th)  ... 
        //or List<Integer> resource(Thumbnail th)  ... 
        //or whatever
    

解析器始终优先于您的实体。这意味着,如果在解析器类中找到具有正确名称、参数和返回类型的解析器方法,则会调用此方法而不是实体方法。这样我们可以“覆盖”实体方法,以返回其他结果,甚至是与实际实体字段不同的类型。通过使用解析器,我们还可以访问实体通常没有的应用程序范围服务等。

编写解析器后,不要忘记将架构文件更新为:

resource: String
#or resource:[Int]
#or whatever

您的架构应该引用解析器类型,因为这是 graphQL 接收的。实际的实体类型将变得与 graphQL 无关。

作为 B 计划,您可以实现一个新的标量。这就像发明一种新的基本类型。这也不是那么难。您可以查看已经存在的标量类型here 并执行类似操作。

然后您可以命名您的新类型 ByteArray 或类似名称,在您的架构中声明它:

scalar ByteArray

然后使用它。

我会选择第一个解决方案,因为它更容易实施。

【讨论】:

以上是关于GraphQL,如何返回字节[]的类型的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 graphq-request 表示嵌套对象输入类型的数组

Apollo GraphQL:用于查询返回不同类型对象的模式?

如何对graphQL中的字段进行运行时数据操作?

带有官方 Graphql 教程的“无法在 CreateUser 类型上查询字段 'id'”

如何在 Next.js 代码优先方法中使用 graphql-type-json 标量

运行突变以存储新用户的帖子返回错误:变量“$data”类型的预期值