Search code examples
javaspringspring-bootgraphqlnullpointerexception

GraphQL query with an not-null object type input returns internal error because its turned into null when examined in code


The Problem

I want to pass an object type, I used MyArr as an example, as an input type in my GraphQL query. When requesting the query, I get an internal error. On further inspection I figured out, that in my code the input is a null reference.

I'm using Java 17, Spring 3.0.5 and SpringGraphQL 1.1.2

My example InputType MyArr:

public class MyArray {

  public MyArray(String[] arr){
    this.arr = arr;
  }

  private String[] arr;

  public String[] getArr() {
    return arr;
  }

My GraphQL Schema:

type Query{
  testQuery(args: MyArr!): String!
}

input {
  arr: [String!]!
}

My GraphQL Resolver:

@Controller
public class RecipesGraphQLController {

@QueryMapping
  public String testQuery(@Argument MyArray arr){
    return arr.getArr()[0];
  }
}

My GraphQL Query (Sent on GraphiQl):

{
  testQuery(args: {arr: ["test"]})
}

What I tried and checked

I checked the GraphQLRequest if the input type is properly sent which it is:

{"query":"{\n  testQuery(args: {arr: [\"test\"]})\n}"}

Then I tried using the complex built-in types in form of a string array as an input type but got the same results:

My GraphQL Schema:

type Query{
  testQuery(args: [String!]!): String!
}

My GraphQL Resolver:

@Controller
public class RecipesGraphQLController {

@QueryMapping
  public String testQuery(@Argument String[] arr){
    return arr[0];
  }
}

My GraphQL Query (Sent on GraphiQl):

{
  testQuery(args: ["test“])
}

When I used simple types as an input, i.e. a string, it worked just fine, which is even more confusing. I tried to debug all the steps Spring goes through until my resolver is called, to see if my input reaches my programm at all. Interestingly, the first call inside of Springs framework, my input is shown but somehow in all the steps Spring goes through its turned into null, so my biggest guess is that its a bug in the current Spring version.

I hope this gives a broad overview of my problem and I'm more than happy to supply further Information.


Solution

  • I finally managed to find the solution:

    When an array is passed as an argument into a GraphQL query, be it as the input itself or as a field of an object type (GraphQL-Java Doc), Spring converts it not to an array but to a list, hence the cryptic binding error.

    Hence the problem was solved by simply changing the field from String[] to List<String>.

    public class MyArray {
    
      public MyArray(String[] arr){
        this.arr = arr;
      }
    
      private String[] arr;
    
      public String[] getArr() {
        return arr;
    }
    

    changed to:

    public class MyArray {
    
      public MyArray(List<String> arr){
        this.arr = arr;
      }
    
      private List<String> arr;
    
      public List<String> getArr() {
        return arr;
    }