express-graphql 解析器参数在解析器中为空,但信息变量值填充了名称和值
express-graphql resolver args is empty in resolver but info variableValues populated with name and value
使用 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,
});
当记录并单步执行 node_modules/graphql/execution/execute.js
时,execute argsOrSchema.variableValues
的第一个参数包含查询参数键和值,但是第 5 个参数 variableValues
未定义。
根据某些线程,例如 this GitHub issue,我可以从解析器的 info
参数中提取 variableValues
,但是我仍然想知道为什么 args
对象是空的?
Here is a gist GraphQL 在 resolver 函数中给出的信息日志
args
参数由传递给正在解析的字段的参数填充——任何传递给 other 字段的参数都不会包含在 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
字段应该只是一个 return 书籍对象,那么从 books
数组中选择正确书籍的逻辑应该包含在该字段的解析器中:
const resolvers = {
Query: {
book: (root, args) => {
return books.find(book => book.title === args.title)
}
},
}
没有理由为 Book
类型的 title
字段包含解析器,除非您需要该字段解析为默认情况下解析的内容以外的其他内容( title
属性 在对象上 return 由父字段的解析器编辑)。这足以按书名查询所有书籍和单本书:
const resolvers = {
Query: {
book: (root, args) => {
return books.find(book => book.title === args.title)
},
books: () => books,
},
}
查看 Apollo 的 official tutorial 以获取更多示例以及解析器工作原理的完整说明。
使用 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,
});
当记录并单步执行 node_modules/graphql/execution/execute.js
时,execute argsOrSchema.variableValues
的第一个参数包含查询参数键和值,但是第 5 个参数 variableValues
未定义。
根据某些线程,例如 this GitHub issue,我可以从解析器的 info
参数中提取 variableValues
,但是我仍然想知道为什么 args
对象是空的?
Here is a gist GraphQL 在 resolver 函数中给出的信息日志
args
参数由传递给正在解析的字段的参数填充——任何传递给 other 字段的参数都不会包含在 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
字段应该只是一个 return 书籍对象,那么从 books
数组中选择正确书籍的逻辑应该包含在该字段的解析器中:
const resolvers = {
Query: {
book: (root, args) => {
return books.find(book => book.title === args.title)
}
},
}
没有理由为 Book
类型的 title
字段包含解析器,除非您需要该字段解析为默认情况下解析的内容以外的其他内容( title
属性 在对象上 return 由父字段的解析器编辑)。这足以按书名查询所有书籍和单本书:
const resolvers = {
Query: {
book: (root, args) => {
return books.find(book => book.title === args.title)
},
books: () => books,
},
}
查看 Apollo 的 official tutorial 以获取更多示例以及解析器工作原理的完整说明。