GraphQL Node.js:确定查询中使用的类型
Posted
技术标签:
【中文标题】GraphQL Node.js:确定查询中使用的类型【英文标题】:GraphQL Node.js: determine what types are used within a query 【发布时间】:2019-04-06 21:34:00 【问题描述】:假设我有一个具有以下类型的架构:用户、评论、帖子、图像;给定查询和模式,是否可以确定查询中使用的 GraphQL 类型? 例如如果客户有查询
user(userName: "username")
email
comments
在这种情况下,查询具有 User 和 Comment 类型。是否可以使用 node.js 的 graphql-js 或 graphql 包以编程方式确定?
【问题讨论】:
【参考方案1】:对于遇到此问题的其他人,我在访问和 TypeInfo 中找到了答案 这是一个函数,它接受 GraphQL 查询(文档)和模式,并返回正在使用的模式中的数据类型。
import visit from 'graphql/language/visitor'
import parse from 'graphql/language'
import TypeInfo, visitWithTypeInfo from 'graphql'
import schema as _schema from '../src/schema/schema'
const getQueryTypes = (schema, query) =>
const typeInfo = new TypeInfo(schema)
var typesMap =
var visitor =
enter(node)
typeInfo.enter(node)
typesMap[typeInfo.getType()] = true
,
leave(node)
typesMap[typeInfo.getType()] = true
typeInfo.leave(node)
visit(parse(query), visitWithTypeInfo(typeInfo, visitor))
return Object.keys(typesMap)
const _query = `
query
...
`
console.log(getQueryTypes(_schema, _query))
【讨论】:
visitWithTypeInfo 是要走的路。但无需手动执行 enter(node) 和 leave(node),因为 visitWithTypeInfo 将创建一个在幕后自动执行此操作的访问者。【参考方案2】:给定一个表示某些 GraphQL 操作的有效文档字符串,您可以将字符串解析为 AST。
import parse, validate from 'graphql'
const document = parse(someDocumentString)
// if you want to validate your document to verify it matches your schema
const errors = validate(schema, document)
AFAIK,如果您需要的话,没有用于获取文档中类型数组的实用函数,但您可以遍历 AST 并从中收集任何信息。例如,以下是 GraphiQL 如何生成变量映射到其对应类型的方法:
import typeFromAST from 'graphql'
export function collectVariables(schema, documentAST)
const variableToType = Object.create(null);
documentAST.definitions.forEach(definition =>
if (definition.kind === 'OperationDefinition')
const variableDefinitions = definition.variableDefinitions;
if (variableDefinitions)
variableDefinitions.forEach(( variable, type ) =>
const inputType = typeFromAST(schema, type);
if (inputType)
variableToType[variable.name.value] = inputType;
);
);
return variableToType;
【讨论】:
【参考方案3】:你必须使用GraphQLObjectType
创建类型,例如:
export default new GraphQLObjectType(
(
name: 'User',
description: 'Represents a User',
fields: () => (
_id:
type: GraphQLNonNull(GraphQLString),
resolve: user => user._id,
,
name:
type: GraphQLNonNull(GraphQLString),
description: 'Name of the user',
resolve: user => user.name,
,
createdAt:
type: GraphQLString,
description: '',
resolve: user => user.createdAt.toISOString(),
,
updatedAt:
type: GraphQLString,
description: '',
resolve: user => user.updatedAt.toISOString(),
,
),
: GraphQLObjectTypeConfig<User, GraphQLContext>),
);
然后你可以在另一个类型上使用这个UserType
,例如声明type: GraphQLNonNull(UserType)
。
https://graphql.org/graphql-js/constructing-types/
希望对你有帮助:)
【讨论】:
感谢丹尼斯的快速回复,我了解如何创建 GraphQL 类型。我想知道的是,如果我有一个查询和一个架构,是否有一个函数/方法可以告诉我查询中使用了架构中的哪些类型。我已将我的 GraphiQL UI 与我的 GraphQL 服务器分开。它们作为单独的应用程序运行,我希望 GraphiQL UI 在将查询发送到 GraphQL 服务器之前能够确定查询中使用了哪些类型。 @user277931 GraphiQL 针对提供的 GraphQL 端点执行自省查询,并根据结果重新生成服务器的架构。此模式用于提供您在使用 GraphiQL 时看到的各种功能,例如 linting、自动完成和文档面板。所以 wrt GraphiQL,它已经知道任何给定字段或参数的类型。所有这些都在引擎盖下为您处理。您到底想通过 GraphiQL 完成什么? @DanielRearden 我们的 graphql 服务器需要处理不同解析器的授权。例如一些客户端可以看到用户和帖子,而其他客户端只能看到用户。为此,我们的客户端必须传入一个名为“Data-Types”的 HTTP 标头,以指定他们尝试发送的类型。它看起来类似于“Data-Types: User,Post”。为了使开发人员更容易做到这一点,我们希望我们的 Graphiql 实例自动确定要包含在“Data-Types”标头中的类型。这有意义吗? 有趣的用例。对于它的价值,您也许还可以创建一个“访问者”(您可以查看示例 github.com/graphql/graphql-js/tree/master/src/validation/rules 的验证规则),然后使用文档的 AST 和访问者对象调用visit
。以上是关于GraphQL Node.js:确定查询中使用的类型的主要内容,如果未能解决你的问题,请参考以下文章
Node.js - 如何使用 graphql 获取关联的模型数据?
Node.js Mongodb GraphQL - 突变和查询
node.js graphql/sequelize 服务器为链接属性返回 null