I have a GraphQL operation which returns a type containing a field. This field takes an argument I'd like to read in the data fetcher.
If the argument is hard-coded (as myArg1
is below), I can directly read its value. If the argument is passed via a variable (as myArg2
is below), I can only read the variable's name, and not its value.
I could manually check each argument's type (e.g., VariableReference
, StringValue
), and accordingly find the variable's value on the DataFetchingEnvironment
, but this is cumbersome. Since GraphQL Java has this info, is it possible for me to directly read the argument's value?
Here's a demo:
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.
Output:
StringValue{value='myVar1'}
VariableReference{name='myArg2'}
There's no way to do this. GraphQL Java doesn't do it because it claims that it doesn't have enough information to give the variable's value when the data fetcher is invoked. This is false because the data fetcher has both the variable's name, and its value. They probably don't want to implement this because they expect you to use DTOs instead. GraphQL Java provides DTOs with the required information.
Create a DTO:
class MyTypeDto {
fun getMyField(env: DataFetchingEnvironment): Boolean {
env.arguments // has the values for both arguments
return false
}
}
and a data fetcher:
dataFetcher("myOperation") { env -> MyTypeDto() }