首页 文章

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

提问于
浏览
49

假设您有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库 .

4 回答

  • 6

    不幸的是,你不想做什么 . GraphQL要求您明确指定要从查询中返回的字段 .

  • 45

    是的,你 can 使用introspection这样做 . 创建一个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命令使用内省来生成类型 .

  • 37

    我想这样做的唯一方法是利用可重用的片段:

    fragment UserFragment on Users {
        id
        username
        count
    } 
    
    FetchUsers {
        users(id: "2") {
            ...UserFragment
        }
    }
    
  • 21

    当我需要从Google Places API加载我已经序列化到数据库中的位置数据时,我遇到了同样的问题 . 一般来说,我想要整个事情,所以它适用于 Map ,但我不想每次都指定所有字段 .

    我在Ruby工作,所以我不能给你PHP实现,但原则应该是相同的 .

    我定义了一个名为JSON的自定义标量类型,它只返回一个文字JSON对象 .

    ruby实现就是这样(使用graphql-ruby)

    module Graph
      module Types
        JsonType = GraphQL::ScalarType.define do
          name "JSON"
          coerce_input -> (x) { x }
          coerce_result -> (x) { x }
        end
      end
    end
    

    然后我用它来做我们的对象

    field :location, Types::JsonType
    

    我会非常谨慎地使用它,只在你知道你总是需要整个JSON对象的地方使用它(正如我在我的情况下所做的那样) . 否则它更普遍地说是打败了GraphQL的对象 .

相关问题