express-graphql解析器args在解析器中为空,但信息变量用名称和值填充的​​值

时间:2019-04-16 15:52:59

标签: graphql graphql-js apollo-server graphql-tools

我使用apollo-server-expressgraphql-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时,execute argsOrSchema.variableValues的第一个参数包含查询参数键和值,但是第5个参数variableValues未定义。

根据某些线程,例如this GitHub issue,我可以从解析器的variableValues参数中拉出info,但是我仍然想知道为什么args对象是空的吗?

GraphQL在解析程序功能中给出的信息日志的

Here is a gist

1 个答案:

答案 0 :(得分:1)

args参数由传递给要解析的字段的参数填充-传递给 other 字段的任何参数将不包含在args参数中。 / p>

您的架构在您的title类型的book字段上包含一个参数(Query)。这意味着该字段的解析器将收到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类型的Book字段添加一个解析程序,除非您需要该字段解析为默认情况下将解析的内容({{ 1}}属性(由父字段的解析器返回)。这足以按标题查询所有书籍和一本书:

title

请参阅Apollo的official tutorial,以获取更多示例,以及有关解析器工作原理的完整说明。