首页 > 解决方案 > 使用模式对 GraphQL 响应进行类型保留反序列化

问题描述

我正在尝试为用户定义的 GraphQL 查询的响应编写反序列化代码。该代码可以访问 JSON 序列化形式的查询响应和底层 GraphQL 模式(通过查询端点schema.json或发出自省请求)。

假设以下架构:

scalar Date

type User {
    name: String
    birthday: Date
}

type Query {
    allUsers: [User]
}

schema {
    query: Query
}

以及以下查询:

query {
    allUsers {
        name
        birthday
    }
}

响应可能如下所示(data.allUsers为简洁起见,仅包括完整响应中的 - 字段):

[
    {"name": "John Doe", "birthday": "1983-12-07"}
]

我试图做的是以保留类型信息的方式反序列化上述响应,包括任何自定义标量。在上面的示例中,按照惯例,我知道 GraphQL 标量Date应该像LocalDate在 Java 中一样反序列化,但仅从响应中我不知道该birthday字段表示 GraphQL 标量类型Date,因为它在 JSON 中被序列化为常规字符串。

能做的是尝试为此使用 GraphQL 模式。对于上面的示例,架构可能看起来像这样(为简洁起见而缩写):

...
"types": [
{
  "kind": "OBJECT",
  "name": "User",
  "fields": [
    {
      "name": "name",
      "type": {
        "kind": "SCALAR",
        "name": "String"
      }
    },
    {
      "name": "birthday"
      "type": {
        "kind": "SCALAR",
        "name": "Date"
      }
    }
...

根据这些信息,我可以推断出该响应的birthday字段是 type Date,并相应地对其进行反序列化。但是,如果查询使用非平凡的 GraphQL 功能,事情就会变得更加复杂。以别名为例:

query {
    allUsers {
        name
        dayOfBirth: birthday
    }
}

在这一点上,我已经需要跟踪任何别名(我可以这样做,因为如果我解析查询,该信息是可用的),并回溯那些以找到正确的类型。我担心如果使用例如片段,它可能会变得更加复杂。

鉴于我使用graphql-java,并且似乎已经需要处理所有这些情况以进行序列化,我想知道是否有比手动回溯查询和模式中的类型更简单的方法来做到这一点。

标签: javagraphqljson-deserializationgraphql-java

解决方案


如何从模式生成 java 类,然后使用这些类进行反序列化。我以前为此使用过一个插件-graphql-java-generator

您可能需要稍微增强插件以支持您的自定义标量

它基本上生成一个 Java 客户端,用于以 Java 方式调用 GraphQL 查询。


推荐阅读