如何在 graphql-java 中使用 java.util.objects 列表定义类型
How to define a type with list of java.util.objects in graphql-java
我有一个模式,其中 json 可以有一个 Int 和 String 列表作为值。我想知道如何为我的场景定义一种类型的解析器。
type Total {
key: String
values: [Object]
}
type Query {
filter (key : String!) : Total
}
GraphQL 中没有一般对象(如Java 中的对象)的概念。事实上,定义的类型如下(如here所述):
- Int:一个带符号的 32 位整数;
- Float:带符号的双精度浮点值;
- 字符串:UTF-8 字符序列;
- 布尔值:真或假;
- ID:ID 标量类型表示唯一标识符,通常用于重新获取对象或用作缓存的键。 ID 类型以与 String 相同的方式序列化;但是,将其定义为 ID 意味着它不是人类可读的。
您可以定义一个新的标量,但这意味着您必须自己定义它的 serialized/deserialized 和验证方式。它增加了更多的复杂性而没有太多价值。此外,我觉得 Graphql 的 strong 类型完全失去了这种特定类型。
我认为最好的选择是使用 Interfaces。通过接口并使用 wrapper types,您就可以对您正在谈论的这个 general object 进行建模,并帮助您编写架构如下:
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
}
我有一个模式,其中 json 可以有一个 Int 和 String 列表作为值。我想知道如何为我的场景定义一种类型的解析器。
type Total {
key: String
values: [Object]
}
type Query {
filter (key : String!) : Total
}
GraphQL 中没有一般对象(如Java 中的对象)的概念。事实上,定义的类型如下(如here所述):
- Int:一个带符号的 32 位整数;
- Float:带符号的双精度浮点值;
- 字符串:UTF-8 字符序列;
- 布尔值:真或假;
- ID:ID 标量类型表示唯一标识符,通常用于重新获取对象或用作缓存的键。 ID 类型以与 String 相同的方式序列化;但是,将其定义为 ID 意味着它不是人类可读的。
您可以定义一个新的标量,但这意味着您必须自己定义它的 serialized/deserialized 和验证方式。它增加了更多的复杂性而没有太多价值。此外,我觉得 Graphql 的 strong 类型完全失去了这种特定类型。
我认为最好的选择是使用 Interfaces。通过接口并使用 wrapper types,您就可以对您正在谈论的这个 general object 进行建模,并帮助您编写架构如下:
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
}