【发布时间】:2019-12-03 23:14:14
【问题描述】:
我有一个模式,其中 json 可以有一个 Int 和 Strings 列表作为值。我想知道如何为我的场景定义一种解析器。
type Total {
key: String
values: [Object]
}
type Query {
filter (key : String!) : Total
}
【问题讨论】:
标签: graphql-java
我有一个模式,其中 json 可以有一个 Int 和 Strings 列表作为值。我想知道如何为我的场景定义一种解析器。
type Total {
key: String
values: [Object]
}
type Query {
filter (key : String!) : Total
}
【问题讨论】:
标签: graphql-java
GraphQL 中没有通用对象的概念(如Java中的Object)。实际上,定义的类型如下(如here所述):
您可以定义一个新的标量,但这意味着您必须自己定义如何对其进行序列化/反序列化和验证。它增加了更多的复杂性,但价值不大。而且,我觉得Graphql的strong类型完全丧失了这种特定类型。
我认为您最好的选择是使用Interfaces。使用接口并使用包装器类型,您就可以对您正在谈论的这个通用对象进行建模,并帮助您编写如下模式:
interface MyInterface {
// must have a field at least (cannot be empty)
id: ID!
}
type MyInt implements MyInteface {
// Inherited by MyInterface
id: ID!
myIntValue: Int
}
type MyString implements MyInteface {
// Inherited by MyInterface
id: ID!
myStringValue: String
}
type Total {
key : String
values: [MyInterface]
}
type Query {
filter(key: String!) : Total
}
注意:请注意界面不能为空(无字段)。为此,我添加了一个由实现随机生成的 ID 字段。
使用这样的架构,我们可以执行如下查询:
filter("someFilter") {
key
values {
... on MyString {
myStringValue
}
... on MyInt {
myIntValue
}
}
}
为此,您需要定义一个 TypeResolver,如下所示:
private class MyInterfaceTypeResolver implements TypeResolver {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
Object obj = env.getObject();
if (obj instanceOf MyInt) {
env.getSchema().getObjectType("MyInt");
} else if (obj instanceOf MyString) {
env.getSchema().getObjectType("MyString");
} else {
return null;
}
}
}
具有以下 Java 类型定义:
abstract class MyInterface {
private String id;
public MyInterface() {
// Generated just to avoid empty graphql interface
id = UUID.randomUUID().toString();
}
public String getId() {
return id;
}
}
class MyInt extends MyInterface {
private Integer myIntValue;
public MyInt(Integer myInt) {
super();
this.myIntValue= myInt;
}
public Integer getMyIntValue() {
return myInt;
}
}
class MyString extends MyInterface {
private String myStringValue;
public MyString (String myString) {
super();
this.myStringValue= myString;
}
public String getMyStringValue() {
return myStringValue;
}
}
假设您要表示以下 Json {"key": "myKey", "values":[12,"String1", 1, "String2"]},给定我们之前的模型和查询,它将表示为:
{
"data": {
"filter": {
"key": "myKey",
"values" : [
{
"myIntValue": 12
},
{
"myStringValue": "String1"
},
{
"myIntValue": 1
},
{
"myStringValue": "String2"
}
]
}
}
}
最后,你可以有多个属性,每个类型一个,例如:
type Total {
key : String
valuesInt: [Int]
valuesString: [String]
}
type Query {
filter(key: String!) : Total
}
【讨论】: