I'm having a mutation defined to update an image object:
mutation updateImage($input: UpdateImageInput!) {
updateImage(input: $input) {
...Image
}
}
The UpdateImageInput
looks like this:
input UpdateImageInput {
id: ID!
version: Int!
title: String
}
When I send a request using the HttpGraphQlTester
I get an error: {message=Variable 'input' has an invalid value: Expected a String input, but it was a 'LinkedHashMap', locations=[{line=1, column=22}
This is how my request looks like
val input = new MyInput(testImage.getId(), testImage.getVersion(),
ArgumentValue.ofNullable("foo"));
val actual = this.gql
.documentName("updateImage")
.fragmentName("fragments/Image")
.fragmentName("fragments/Address")
.fragmentName("fragments/LinkedPlanningObject")
.variable("input", input)
.execute()
.errors()
.verify()
.path("updateImage")
.entity(Image.class)
.get();
When I remove the ArgumentValue
and just use a String in my input object, then there is no error.
The application works well with another client like graphiql.
Am I missing something or is there any way to configure the client to use the ArgumentValue?
In Spring for GraphQL, ArgumentValue
is a reference type designed to know whether a value is absent/null
/present. It's mostly designed with the server-side in mind. But I agree that the client side has been overlooked.
To simply answer your question, this is currently not possible and you would need to write a custom Jackson Serializer to deal with this case right now.
We (the Spring GraphQL team) could improve the situation. We would need to plug in a customization mechanism in the JSON serialization library to omit that property when ArgumentValue.ommitted()
. I have looked into this and the best I came up with was a Jackson PropertyFilter
. Unfortunately, this needs to be manually associated with your type, so it's not 100% transparent.
Assuming we automatically register an "argumentValue"
filter for you, this still means your MyInput
type needs to be annotated like this:
@JsonFilter("argumentValue")
record MyInput(String id, int version, ArgumentValue<String> title) {
}
Would this be an acceptable solution to you?
Edit: I have created an issue to track this feature request: https://github.com/spring-projects/spring-graphql/issues/1166