我们如何递归地自省 GraphQL 模式?
Posted
技术标签:
【中文标题】我们如何递归地自省 GraphQL 模式?【英文标题】:How can we introspect a GraphQL schema recursively? 【发布时间】: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”)?她似乎无法从上述结果中知道authors
是Author
的列表。有没有办法让她进一步反省?
【问题讨论】:
【参考方案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
如果kind
是OBJECT
,则其fields
字段将被适当地填充。然后,您可以像上面一样请求每个字段的详细信息。当然,如果那些字段返回了任何 OBJECT,您必须指定要从这些字段中获取哪些信息。
你可以阅读更多关于自省的内容here。
内省可能非常混乱。如果您需要一种让 GraphQL 端点的使用者探索模式的方法,那么 GraphiQL 是一种更加用户友好的方式。还有动态生成文档的方法 (like this)。
【讨论】:
以上是关于我们如何递归地自省 GraphQL 模式?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 GraphQL 生成 Dart - graphql 到 dart 生成器