我正在尝试使用fetch编写基本的graphql查询,该查询在使用阿波罗客户端时有效。但这不适用于节点获取。
类型定义如下:
type Query {
findLeadStat(print: PrintInput!): LeadStatWithPrint
}
input PrintInput {
printa: String!
service: String
}
type LeadStatWithPrint {
answered: Int!
printa: String!
service: String
}
这是节点获取查询:
const fetch = require('node-fetch');
( async () => {
const uri = `http://localhost:3000/graphql/v1`;
const query = `
query findLeadStat(print: PrintInput!) {
findLeadStat(print: $print){
answered
printa
service
}
}
`;
// I also tried add a query: key inside data object
const data = {
print: {
printa: "62f69234a7901e3659bf67ea2f1a758d",
service: "abc"
}
}
const response = await fetch(uri, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({query, data})
});
console.log('and the resp: ', response);
})()
它给了我
url: 'http://localhost:3000/graphql/v1',
status: 400,
statusText: 'Bad Request',
它可在Apollo GraphQL Client中使用。为什么提取不起作用?
因此,当我使用带有节点获取功能的异步等待时,响应几乎没有用。只是告诉我有一个400错误的请求错误,然后再给我这个很长的属性对象,这些属性都不包含实际的错误消息。
但是当我将fetch调用更改为此:
const response = await fetch(uri, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ query, variables}) // same as query: query, variables: variables
})
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('ERROR: ', err));
这里有两行:
.then(res => res.json())
.then(json => console.log(json))
明确了问题所在:
{
errors: [
{
message: 'Syntax Error: Expected $, found Name "fingeprint"',
locations: [Array],
extensions: [Object]
}
]
}
似乎node-fetch发生了两个异步事件,因此await必须使用两次:
const response = await fetch(uri, {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ query, variables}) // same as query: query, variables: variables
})
console.log('and the resp: ', await response.json());
答案 0 :(得分:1)
状态为400表示您的查询无效或格式错误。发生这种情况时,响应中将包含一个带有errors
数组的JSON正文,可以对其进行检查以确定到底出了什么问题。
在这种特殊情况下,问题是您的查询包含不可为空的变量($print
),但查询未提供此变量。
发出GraphQL请求时,请求主体应该是具有query
属性和两个其他可选属性variables
和operationName
的JSON对象。 operationName
用于标识如果提供的文档中包含多个操作(query
属性),则执行哪个操作。在执行的操作中定义的任何非空变量必须作为属性包含在variables
属性下,该属性也是一个对象。可空属性可能会完全省略。
换句话说,您需要将请求中的data
属性更改为variables
,以便服务器识别该变量是随请求提供的。