我正在尝试为用户定义的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
在Java中应反序列化为LocalDate
,但是仅从响应中我就不知道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
字段的类型为Date
,并相应地对其进行反序列化。但是,如果查询使用非平凡的GraphQL功能,事情就会变得更加复杂。以别名为例:
query {
allUsers {
name
dayOfBirth: birthday
}
}
在这一点上,我已经需要跟踪任何别名(我可以这样做,因为如果我解析查询,该信息就可用),然后回溯那些别名以找到正确的类型。我担心如果例如使用碎片。
鉴于我使用了graphql-java
,并且看来已经需要处理所有这些情况以进行序列化,我想知道是否有比手动回溯更简便的方法查询和架构中的类型。
答案 0 :(得分:1)
如何从架构中生成Java类,然后使用这些类进行反序列化。我以前曾为此使用过一个插件-graphql-java-generator
您可能需要对插件进行一些增强,以支持您的自定义标量
它基本上会生成一个Java客户端,以Java方式调用您的GraphQL查询。
答案 1 :(得分:0)
我在反序列化 LocalDate 属性时遇到了同样的问题,即使使用 graphql-java-extended-scalars 库也是如此。
经过研究,我发现这个库适用于查询,但不适用于突变。
我通过自定义 SchemaParserOptions 解决了我的问题,如下所示:
@Bean
public SchemaParserOptions schemaParserOptions() {
return SchemaParserOptions.newOptions().objectMapperConfigurer((mapper, context) -> {
mapper.registerModule(new JavaTimeModule());
}).build();
}
在对象中我没有使用任何序列化和反序列化注释。