读取通过 GraphQL 中的变量传递的字段参数 Java
Read argument on field passed via variable in GraphQL Java
我有一个 GraphQL 操作,其中 returns 一个包含字段的类型。该字段采用我想在数据获取器中读取的参数。
如果参数是硬编码的(如下面的myArg1
),我可以直接读取它的值。如果参数是通过变量传递的(如下面的 myArg2
),我只能读取变量的名称,而不是它的值。
我可以手动检查每个参数的类型(例如,VariableReference
、StringValue
),并相应地在 DataFetchingEnvironment
上找到变量的值,但这很麻烦。由于 GraphQL Java 有这个信息,我可以直接读取参数的值吗?
这是一个演示:
val registry = SchemaParser().parse(
"""
type Query {
myOperation: MyType!
}
type MyType {
myField(myArg1: String!, myArg2: String!): Boolean!
}
"""
)
val wiring = newRuntimeWiring()
.type("Query") { builder ->
builder.dataFetcher("myOperation") { env ->
val myField = env.mergedField.singleField.selectionSet.selections[0] as Field
val args = myField.arguments.map { it.value }
println(args[0])
println(args[1])
true
}
}
.build()
val schema = SchemaGenerator().makeExecutableSchema(registry, wiring)
val graphQl = newGraphQL(schema).build()
val query = """
query MyOperation(${"$"}myArg2: String!) {
myOperation {
myField(myArg1: "myVar1", myArg2: ${"$"}myArg2)
}
}
"""
val builder = ExecutionInput.Builder().query(query).variables(mapOf("myArg2" to "myVar2"))
graphQl.execute(builder) // Trigger data fetcher.
输出:
StringValue{value='myVar1'}
VariableReference{name='myArg2'}
没必要这么复杂。如果你在 'myField' 的数据获取器中,你可以简单地使用 env.getArgument()
获取参数的值:
String myArgumentValue = env.getArgument("myArgument");
对于输入类型参数,它会return一个Map。 (参见 )。对于标量参数 ,java 对象类型将 returned 取决于基础标量实现的 Coercing
。
没有办法做到这一点。 GraphQL Java 没有这样做,因为它声称在调用数据获取器时没有足够的信息来提供变量的值。这是错误的,因为数据获取器既有变量的名称,也有它的值。他们可能不想实现这一点,因为他们希望您改为使用 DTO。 GraphQL Java 为 DTO 提供所需的信息。
创建 DTO:
class MyTypeDto {
fun getMyField(env: DataFetchingEnvironment): Boolean {
env.arguments // has the values for both arguments
return false
}
}
和一个数据获取器:
dataFetcher("myOperation") { env -> MyTypeDto() }
您可以通过以下方式到达那里。你需要 trim !来自类型名称的修饰符。
使用这种在 DataFetcher 中遍历架构的方法我还没有弄清楚的一件事是,有时字段定义参数会解析为 GraphQLInputObjectTypes,在这种情况下,您需要转换它们并调用 getName()。
environment.getFieldDefinition().getArguments().forEach((arg) -> {
System.out.println("Env field def arg: " + arg.getName() + ", type: " + arg.getType().toString());
});
我有一个 GraphQL 操作,其中 returns 一个包含字段的类型。该字段采用我想在数据获取器中读取的参数。
如果参数是硬编码的(如下面的myArg1
),我可以直接读取它的值。如果参数是通过变量传递的(如下面的 myArg2
),我只能读取变量的名称,而不是它的值。
我可以手动检查每个参数的类型(例如,VariableReference
、StringValue
),并相应地在 DataFetchingEnvironment
上找到变量的值,但这很麻烦。由于 GraphQL Java 有这个信息,我可以直接读取参数的值吗?
这是一个演示:
val registry = SchemaParser().parse(
"""
type Query {
myOperation: MyType!
}
type MyType {
myField(myArg1: String!, myArg2: String!): Boolean!
}
"""
)
val wiring = newRuntimeWiring()
.type("Query") { builder ->
builder.dataFetcher("myOperation") { env ->
val myField = env.mergedField.singleField.selectionSet.selections[0] as Field
val args = myField.arguments.map { it.value }
println(args[0])
println(args[1])
true
}
}
.build()
val schema = SchemaGenerator().makeExecutableSchema(registry, wiring)
val graphQl = newGraphQL(schema).build()
val query = """
query MyOperation(${"$"}myArg2: String!) {
myOperation {
myField(myArg1: "myVar1", myArg2: ${"$"}myArg2)
}
}
"""
val builder = ExecutionInput.Builder().query(query).variables(mapOf("myArg2" to "myVar2"))
graphQl.execute(builder) // Trigger data fetcher.
输出:
StringValue{value='myVar1'}
VariableReference{name='myArg2'}
没必要这么复杂。如果你在 'myField' 的数据获取器中,你可以简单地使用 env.getArgument()
获取参数的值:
String myArgumentValue = env.getArgument("myArgument");
对于输入类型参数,它会return一个Map。 (参见 Coercing
。
没有办法做到这一点。 GraphQL Java 没有这样做,因为它声称在调用数据获取器时没有足够的信息来提供变量的值。这是错误的,因为数据获取器既有变量的名称,也有它的值。他们可能不想实现这一点,因为他们希望您改为使用 DTO。 GraphQL Java 为 DTO 提供所需的信息。
创建 DTO:
class MyTypeDto {
fun getMyField(env: DataFetchingEnvironment): Boolean {
env.arguments // has the values for both arguments
return false
}
}
和一个数据获取器:
dataFetcher("myOperation") { env -> MyTypeDto() }
您可以通过以下方式到达那里。你需要 trim !来自类型名称的修饰符。
使用这种在 DataFetcher 中遍历架构的方法我还没有弄清楚的一件事是,有时字段定义参数会解析为 GraphQLInputObjectTypes,在这种情况下,您需要转换它们并调用 getName()。
environment.getFieldDefinition().getArguments().forEach((arg) -> {
System.out.println("Env field def arg: " + arg.getName() + ", type: " + arg.getType().toString());
});