express-graphql 解析器参数在解析器中为空,但 info variableValues 填充了名称和值
Posted
技术标签:
【中文标题】express-graphql 解析器参数在解析器中为空,但 info variableValues 填充了名称和值【英文标题】:express-graphql resolver args is empty in resolver but info variableValues populated with name and value 【发布时间】:2019-09-06 19:02:01 【问题描述】:使用apollo-server-express
和graphql-tools
,我正在尝试从JSON 对象创建一个最小可行的架构:
const books = [
"title": "Harry Potter",
"author": 'J.K. Rowling',
"slug": "harry_potter",
,
"title": 'Jurassic Park',
"author": 'Michael Crichton',
"slug": "jurassic_park",
,
];
// The GraphQL schema in string form
const typeDefs = `
type Query
books: [Book]
book(title: String!): Book
type Book title: String!, author: String!, slug: String!
`;
// The resolvers
const resolvers =
Query:
books: () => books,
book: (_, title ) => books.filter(book =>
return new Promise((resolve, reject) =>
if(book.title == title)
console.log('hack log resolve book _: ', JSON.stringify(book))
resolve(JSON.stringify(book));
)
),
,
Book:
title: (root, args, context, info) =>
//args is empty, need to match arg w book.title
/*
context:
_extensionStack:
GraphQLExtensionStack
extensions: [ [FormatErrorExtension], [CacheControlExtension] ]
, root,
*/
console.log('resolve Book args: ', args, 'info', info);//JSON.stringify(root.book))
return books.filter(book =>
if(book.title == root.title)
return book;
);//JSON.stringify("title": root.title);
;
// book: (_, title ) => books.filter(book => book.title == title),
// Put together a schema
const schema = makeExecutableSchema(
typeDefs,
resolvers,
);
这是my repository。
当记录和单步执行node_modules/graphql/execution/execute.js
时,执行argsOrSchema.variableValues
的第一个参数包含查询参数键和值,但是第五个参数variableValues
未定义。
根据this GitHub issue等一些线程,我可以从解析器的info
参数中提取variableValues
,但是我仍然想知道为什么args
对象为空?
Here is a gist GraphQL 在解析器函数中给出的信息日志
【问题讨论】:
【参考方案1】:args
参数由传递给正在解析的字段的参数填充 -- 传递给 其他 字段的任何参数都不会包含在 args
参数中。
您的架构在您的 Query
类型的 book
字段中包含一个参数 (title
)。这意味着该字段的解析器将接收 title
参数作为其 args
参数的一部分,但前提是该参数实际上包含在您的查询中:
// Request
query
book(title: "Something")
title
// Resolvers
const resolvers =
Query:
book: (root, args) =>
console.log(args) // title: 'Something'
,
相对于:
// Request
query
book
title
// Resolvers
const resolvers =
Query:
book: (root, args) =>
console.log(args) //
,
如果您为title
参数传入一个值,那么在解析器中为其他字段获取该值的唯一方法是解析info
参数。您不会查看variableValues
属性,因为传递给参数的值可能是文字值或变量。您需要遍历 fieldNodes
数组并找到适当的参数值。
但是,通常不需要经历所有这些。
如果book
字段应该只返回一个书本对象,则从books
数组中选择正确书籍的逻辑应该包含在该字段的解析器中:
const resolvers =
Query:
book: (root, args) =>
return books.find(book => book.title === args.title)
,
没有理由在 title
类型上包含 title
字段的解析器,除非您需要该字段解析为默认情况下将解析的内容(title
上的属性由父字段的解析器返回的对象)。这足以按标题查询所有书籍和单本书:
const resolvers =
Query:
book: (root, args) =>
return books.find(book => book.title === args.title)
,
books: () => books,
,
查看来自 Apollo 的 official tutorial 以获取更多示例以及解析器工作原理的完整说明。
【讨论】:
以上是关于express-graphql 解析器参数在解析器中为空,但 info variableValues 填充了名称和值的主要内容,如果未能解决你的问题,请参考以下文章