在axios中进行GraphQL的post请求

25

我在使用GraphQL时遇到了问题。我想发送axios.post请求到我的服务器。我可以在Postman中完成:

{
    "query":"mutation{updateUserCity(userID: 2, city:\"test\"){id name age city knowledge{language frameworks}}} "
}

同时在GraphiQL中:

mutation {
  updateUserCity(userID: 2, city: "test") {
    id
    name
    age
    city
    knowledge {
      language
      frameworks
    }
  }
}

但是我无法在我的代码中做到这一点:(( 这是我的代码片段:

const data = await axios.post(API_URL, {
  query: mutation updateUserCity(${ id }: Int!, ${ city }: String!) {
    updateUserCity(userID: ${ id }, city: ${ city }){
      id
      name
      age
      city
      knowledge{
        language
        frameworks
      }
    }
  }
}, {
    headers: {
      'Content-Type': 'application/json'
    }
  })

我的代码有什么问题?


可能是一个很好的参考,看起来查询字符串中没有数据。https://medium.com/@stubailo/how-to-call-a-graphql-server-with-axios-337a94ad6cf9 - Austio
不,我尝试过那种方法,但没有帮助。 - Tatevik
https://graphql.org/graphql-js/passing-arguments/ - xadm
6个回答

60

要传递给请求的query参数的值必须是字符串,并且传递到GraphQL查询的变量名称应以$为前缀。您在请求中使用了字符串文字代替变量。此外,可以使用variables键在post请求中传递变量。

将您的代码更改为以下内容应该可以正常工作:

const data = await axios.post(API_URL, {
  query: `mutation updateUserCity($id: Int!, $city: String!) {
    updateUserCity(userID: $id, city: $city){
      id
      name
      age
      city
      knowledge{
        language
        frameworks
      }
    }
  }`,
  variables: {
    id: 2,
    city: 'Test'
  }
}, {
    headers: {
      'Content-Type': 'application/json'
    }
  })

2
我不得不用反引号将花括号包装在变量中,以使其正常工作。 - ihossain
如果参数是自定义类型,该怎么办? - Dev AKS
@DevAKS:我不明白你所说的自定义类型是什么意思。你能否举个例子分享一下? - Raeesaa
@Raeesaa,你在mutation中接受Int和String变量作为参数,那么我们可以使用用户定义类型,例如-位置{lat:Int,lng:Int}。 - Dev AKS
@DevAKS https://graphql.org/learn/queries/#variables https://graphql.org/learn/schema/#input-types - xadm
如果需要 headers,则 axios.post() 有三个参数,否则为2个。 - Timo

12

我喜欢使用以下语法,它类似于被接受的答案,但更加明确。

请注意,variables对象嵌套在data对象内部,并且是query对象的同级。

const data = await axios({
  url: API_URL,
  method: 'post',
  headers: {
    'Content-Type': 'application/json',
    // ...other headers
  },
  data: {
    query: `
      mutation updateUserCity($id: Int!, $city: String!) {
        updateUserCity(userID: $id, city: $city) {
          id
          name
          age
          city
          knowledge {
            language
            frameworks
          }
        }
      }
    `,
    variables: {
      id: 2,
      city: 'Test'
    }
  }
});

需要对data使用JSON.stringify()吗? - Timo
@Timo,使用axios时不需要对data进行JSON.stringify()。参考链接:https://axios-http.com/docs/api_intro - NWRichmond

2
我很乐意为您提供一个简单的工作示例。最初的回答是:

我想与您分享我的简单工作示例。

            let id = "5c9beed4a34c1303f3371a39";
            let body =  { 
                query: `
                    query {
                        game(id:"${id}") {
                            _id
                            title
                        }
                    }
                `, 
                variables: {}
            }
            let options = {
                headers: {
                    'Content-Type': 'application/json'
                }
            }
            axios.post('http://localhost:3938/api/v1/graphql',body, options)
                .then((response)=>{
                    console.log(response);
                });

1
这不是应该的做法。GraphQL有一个专门的变量接口,当输入包含引号时很容易出错。 - WoLfulus
这个方法对我很有效,稍作修改后就成功了。谢谢! - cpit
1
使用字符串字面量作为变量是滥用 GraphQL,远不如安全、可读和可管理。 - xadm

1

针对WordPress GQL https://docs.wpgraphql.com/getting-started/posts/ 这似乎是我目前在Nuxt上使用的有效方法

async asyncData() {
const data = {
  query: `query GET_POSTS($first: Int) {
    posts(first: $first) {
      edges {
        node {
          postId
          title
          excerpt
          date
          content
          author {
            node {
              username
            }
          }
        }
      }
    }
  }`,
  variables: {
    first: 5
  }
}

const options = {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  data: data,
  url: 'http://localhost/graphql'
};
    
try {
  const response = await axios(options);

  console.log(response.data.data.posts.edges);
  console.log(response.data.data.posts.edges.length);
} catch (error) {
  console.error(error);
}

},


0

看起来你正在尝试将变量传递到查询中。除非我错了,否则你在axios调用和其他地方的内容是不同的。

const data = await axios.post(API_URL, {
  query: `
    updateUserCity(userID: ${id}, city:${city}){
      id
      name
      age
      city
      knowledge{
        language
        frameworks
      }
    }
  `
}, {
  headers: {
    'Content-Type': 'application/json'
  }
});

我相信这应该可以工作,假设在调用此函数之前已经定义了变量idcity


1
这不是应该的做法。GraphQL有一个专门的变量接口,当输入包含引号时很容易出错。 - WoLfulus

0

像这样传递数据:

const email = "test@gmail.com";
const password = "123";

const data = await axios.post(
  API_URL.Loging,
  {
    query: `query{
      login(
        email:"${email}", 
        password:"${password}"
      )
      {
        userId
        token
      }
    }`,
  }
);
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接