如何在不编写长查询的情况下查询所有 GraphQL 类型字段?

2022-08-30 06:08:11

假设您有一个 GraphQL 类型,它包含许多字段。如何在不写下包含所有字段名称的长查询的情况下查询所有字段?

例如,如果我有这些字段:

 public function fields()
    {
        return [
            'id' => [
                'type' => Type::nonNull(Type::string()),
                'description' => 'The id of the user'
            ],
            'username' => [
                'type' => Type::string(),
                'description' => 'The email of user'
            ], 
             'count' => [
                'type' => Type::int(),
                'description' => 'login count for the user'
            ]

        ];
    }

要查询所有字段,通常查询如下所示:

FetchUsers{users(id:"2"){id,username,count}}

但是我想要一种方法来获得相同的结果,而无需编写所有字段,如下所示:

FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}

有没有办法在 GraphQL 中做到这一点?

我正在使用Folkloreatelier/laravel-graphql库。


答案 1

不幸的是,你想做的事情是不可能的。GraphQL 要求您明确指定要从查询中返回的字段。


答案 2

是的,您可以使用内省来执行此操作。像 GraphQL 查询一样(对于类型 UserType)

{
   __type(name:"UserType") {
      fields {
         name
         description
      }  
   }
}

并且你会得到一个类似这样的响应(实际的字段名称将取决于您的实际架构/类型定义)

{
  "data": {
    "__type": {
      "fields": [
        {
          "name": "id",
          "description": ""
        },
        {
          "name": "username",
          "description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
        },
        {
          "name": "firstName",
          "description": ""
        },
        {
          "name": "lastName",
          "description": ""
        },
        {
         "name": "email",
          "description": ""
        },
        ( etc. etc. ...)
      ]
    }
  }
}

然后,您可以在客户端中读取此字段列表,并动态构建第二个 GraphQL 查询以获取所有这些字段的值。

这取决于您知道要获取其字段的类型的名称 - 如果您不知道该类型,则可以使用内省将所有类型和字段放在一起,例如

{
  __schema {
    types {
      name
      fields {
        name
        description
      }
    }
  }
}

注意:这是在线 GraphQL 数据 - 您可以自己弄清楚如何使用实际客户端进行读取和写入。你的 graphQL javascript 库可能已经在某些能力上采用了内省,例如 apollo codegen 命令使用内省来生成类型。

20222 更新

由于此答案最初是编写的,因此现在建议在生产中关闭内省。参考:为什么你应该在生产中禁用 graphql 自省

对于在生产中关闭自检的环境,您可以在开发中使用它作为帮助创建在生产中使用的静态查询的一种方式。您实际上无法在生产环境中动态创建查询。


推荐