读取通过 G​​raphQL 中的变量传递的字段参数 Java

Read argument on field passed via variable in GraphQL Java

我有一个 GraphQL 操作,其中 returns 一个包含字段的类型。该字段采用我想在数据获取器中读取的参数。

如果参数是硬编码的(如下面的myArg1),我可以直接读取它的值。如果参数是通过变量传递的(如下面的 myArg2),我只能读取变量的名称,而不是它的值。

我可以手动检查每个参数的类型(例如,VariableReferenceStringValue),并相应地在 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());
});