具有非 null 对象类型输入的 GraphQL 查询返回内部错误,因为在代码中检查时它变为 null

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

提问人:fnymmm 提问时间:4/21/2023 最后编辑:fnymmm 更新时间:4/24/2023 访问量:491

问:

问题

我想传递一个对象类型,我使用 MyArr 作为示例,作为我的 GraphQL 查询中的输入类型。请求查询时,我收到一个内部错误。在进一步检查时,我发现在我的代码中输入是一个空引用。

我正在使用 Java 17、Spring 3.0.5 和 SpringGraphQL 1.1.2

我的示例 InputType MyArr:

public class MyArray {

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

  private String[] arr;

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

我的 GraphQL 架构:

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

input {
  arr: [String!]!
}

我的 GraphQL 解析器:

@Controller
public class RecipesGraphQLController {

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

我的 GraphQL 查询(在 GraphiQl 上发送):

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

我尝试并检查了什么

我检查了 GraphQLRequest 是否正确发送了输入类型,它是:

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

然后我尝试使用字符串数组形式的复杂内置类型作为输入类型,但得到了相同的结果:

我的 GraphQL 架构:

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

我的 GraphQL 解析器:

@Controller
public class RecipesGraphQLController {

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

我的 GraphQL 查询(在 GraphiQl 上发送):

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

当我使用简单类型作为输入(即字符串)时,它工作得很好,这更加令人困惑。 我试图调试 Spring 所经历的所有步骤,直到调用我的解析器,看看我的输入是否到达我的程序。有趣的是,在 Springs 框架内部的第一次调用中,我的输入被显示出来,但不知何故,在 Spring 经历的所有步骤中,它变成了 null,所以我最大的猜测是这是当前 Spring 版本中的一个错误。

我希望这能对我的问题有一个广泛的概述,我非常乐意提供进一步的信息。

java spring-boot graphql nullpointerexception

评论

0赞 fnymmm 4/21/2023
我用参数的名称扩展了注释: 但同样的问题仍然存在java @QueryMapping public String testQuery(@Argument(name = "arr") MyArray arr){ return arr.getArr()[0]; }

答:

0赞 fnymmm 4/22/2023 #1

我终于找到了解决方案:

当数组作为参数传递到 GraphQL 查询中时,无论是作为输入本身还是作为对象类型的字段(GraphQL-Java Doc),Spring 都不会将其转换为数组而是将其转换为列表,因此会出现隐晦的绑定错误。

因此,只需将字段从 String[] 更改为 List<String>,问题就解决了。

public class MyArray {

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

  private String[] arr;

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

改为:

public class MyArray {

  public MyArray(List<String> arr){
    this.arr = arr;
  }

  private List<String> arr;

  public List<String> getArr() {
    return arr;
}