【问题标题】:How can we introspect a GraphQL schema recursively?我们如何递归地自省 GraphQL 模式?
【发布时间】:2018-06-26 01:30:50
【问题描述】:

如果客户不知道架构并且想自省和理解 GraphQL API,那么 GraphQL 似乎无法支持递归自省。关于我的观点,请参见以下示例

首先,以下是我在高层的架构定义:

// schema.js
...
...     
const AuthorType = new GraphQLObjectType({
  name: "Author",
  description: "This represent an author",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    name: {type: new GraphQLNonNull(GraphQLString)},
    twitterHandle: {type: GraphQLString}
  })
});

const PostType = new GraphQLObjectType({
  name: "Post",
  description: "This represent a Post",
  fields: () => ({
    id: {type: new GraphQLNonNull(GraphQLString)},
    title: {type: new GraphQLNonNull(GraphQLString)},
    body: {type: GraphQLString},
    author: {
      type: AuthorType,
      resolve: function(post) {
        return _.find(Authors, a => a.id == post.author_id);
      }
    }
  })
});

// This is the Root Query
const BlogQueryRootType = new GraphQLObjectType({
  name: 'BlogAppSchema',
  description: "Blog Application Schema Query Root",
  fields: () => ({
    authors: {
      type: new GraphQLList(AuthorType),
      description: "List of all Authors",
      resolve: function() {
        return Authors
      }
    },
    posts: {
      type: new GraphQLList(PostType),
      description: "List of all Posts",
      resolve: function() {
        return Posts
      }
    }
  })
});

当有人使用以下查询子句查询架构时:

{
  __type(name: "BlogAppSchema") {
    name
    fields {
      name
      description
      type {
        name
      }
    }
  }
}

她得到以下结果:

{
  "data": {
    "__type": {
      "name": "BlogAppSchema",
      "fields": [
        {
          "name": "authors",
          "description": "List of all Authors",
          "type": {
            "name": null
          }
        },
        {
          "name": "posts",
          "description": "List of all Posts",
          "type": {
            "name": null
          }
        }
      ]
    }
  }
}

阅读源码,我们知道作者是一个AuthorType的列表。但是没有访问源代码的用户如何从上面得到的结果中进一步内省“作者”字段(类型字段在这里显示“null”)?她似乎无法从上述结果中知道authorsAuthor 的列表。有没有办法让她进一步反省?

【问题讨论】:

    标签: graphql graphql-js


    【解决方案1】:

    name 字段返回 null,因为您的 AuthorType 被 GraphQLList 包装器包装。这意味着该字段正在返回有关包装器的信息,而不是底层类型。要获取该类型,您需要修改您的请求:

    {
      __type(name: "BlogAppSchema") {
        name
        fields {
          name
          description
          type {
            name
            kind # this will show NON_NULL, LIST, SCALAR or OBJECT
            ofType { # if NON_NULL or LIST what is it a non-null or list *of*
              name
              kind
              # other fields, like "fields" which will be populated for an OBJECT
            }
          }
        }
      }
    }
    

    如果您使用多个包装器(即 [Author]! 或 [Author!]!),您将需要“更深入”并请求嵌套的 ofType 字段:

    {
      __type(name: "BlogAppSchema") {
        name
        fields {
          name
          description
          type {
            name
            kind 
            ofType { 
              name
              kind
              ofType {
                name
                kind
                ofType {
                  name
                  kind
                  ofType {
                    name
                    kind
                  }
                }
              }
            }
          }
        }
      }
    }
    

    如果kindOBJECT,则其fields 字段将被适当地填充。然后,您可以像上面一样请求每个字段的详细信息。当然,如果那些字段返回了任何 OBJECT,您必须指定要从这些字段中获取哪些信息。

    你可以阅读更多关于自省的内容here

    内省可能非常混乱。如果您需要一种让 GraphQL 端点的使用者探索模式的方法,那么 GraphiQL 是一种更加用户友好的方式。还有动态生成文档的方法 (like this)。

    【讨论】:

      猜你喜欢
      • 2021-02-07
      • 2014-08-30
      • 2017-03-07
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 2021-12-25
      • 2017-07-24
      • 1970-01-01
      相关资源
      最近更新 更多