我有一个架构,其中json可以将Int和Strings的列表作为值。我想知道如何为我的方案定义一种解析器。
type Total {
key: String
values: [Object]
}
type Query {
filter (key : String!) : Total
}
答案 0 :(得分:1)
在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字段,该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
}