首页 文章

我们如何递归地内省GraphQL模式?

提问于
浏览
0

如果客户不知道架构并且想要内省并理解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的列表 . 但是,如果没有访问源代码的用户如何从上面得到的结果中进一步反思'authors'的字段(类型字段在这里显示"null")?她似乎无法知道 authors 是上述结果的 Author 列表 . 有没有办法让她进一步反省?

1 回答

  • 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
            }
          }
        }
      }
    }
    

    如果您使用多个包装器(即[作者]!或[作者!]!),则需要"go deeper"并请求嵌套的 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 字段 . 然后,您可以按上述方式请求每个字段的详细信息 . 当然,如果从 those 字段返回任何OBJECT,您必须指定要从这些字段中获取的信息 .

    您可以阅读有关内省here的更多信息 .

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

相关问题