【问题标题】:graphql query with fetch producing 400 bad request带有 fetch 的 graphql 查询产生 400 个错误请求
【发布时间】:2020-08-05 19:49:01
【问题描述】:

我正在尝试使用 fetch 编写一个基本的 graphql 查询,该查询在使用 apollo 客户端时有效。但它不适用于 node-fetch。

类型定义如下所示:

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 客户端。为什么它不能与 fetch 一起使用?

因此,当我将 async await 与 node-fetch 一起使用时,响应几乎毫无用处。它只是告诉我有一个 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());

【问题讨论】:

    标签: javascript node.js graphql


    【解决方案1】:

    400 状态表示您的查询无效或格式错误。发生这种情况时,响应将包含一个带有 errors 数组的 JSON 正文,可以检查该数组以确定究竟出了什么问题。

    在这种特殊情况下,问题在于您的查询包含一个不可为空的变量 ($print),但该变量未随查询一起提供。

    发出 GraphQL 请求时,请求正文应该是一个 JSON 对象,具有一个 query 属性和另外两个可选属性——variablesoperationNameoperationName 用于标识在提供的文档中包含多个操作时要执行的操作(query 属性)。在执行的操作中定义的任何不可为空的变量都必须作为属性包含在variables 属性下,该属性也是一个对象。可以完全忽略可为空的属性。

    换句话说,您需要将请求中的data 属性更改为variables,以便服务器识别该变量是随请求提供的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-19
      • 1970-01-01
      • 2021-12-03
      • 2020-07-16
      • 2017-03-23
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      相关资源
      最近更新 更多