How to Use Axios with GraphQL APIs
Using Axios to interact with GraphQL endpoints is a lightweight alternative to dedicated GraphQL clients like Apollo Client or Relay. Because GraphQL operates primarily over HTTP using standard POST requests, Axios can seamlessly send queries, mutations, and variables by transmitting a structured JSON payload to the server. This guide covers how to set up Axios for GraphQL, execute queries and mutations, pass dynamic variables, and handle GraphQL-specific response structures and errors.
The Anatomy of a GraphQL Request in Axios
GraphQL servers typically expose a single HTTP POST endpoint (e.g.,
/graphql). The request body must be a JSON object
containing at least a query field as a string. Optionally,
it can include a variables field containing dynamic
values.
Making a Basic Query
To fetch data, define your GraphQL query string and send it inside
the request body using axios.post():
import axios from 'axios';
const fetchUserData = async () => {
const endpoint = 'https://api.example.com/graphql';
const query = `
query GetUser {
user(id: "123") {
id
name
email
}
}
`;
try {
const response = await axios.post(
endpoint,
{ query },
{
headers: {
'Content-Type': 'application/json',
},
}
);
console.log(response.data.data.user);
} catch (error) {
console.error('Network Error:', error);
}
};Using Dynamic Variables
Hardcoding values into query strings can lead to injection issues and
poor reusability. Pass dynamic parameters using GraphQL variables and
include a variables object alongside the query
in the Axios payload.
const fetchUserWithVariables = async (userId) => {
const endpoint = 'https://api.example.com/graphql';
const query = `
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
const variables = {
id: userId,
};
const response = await axios.post(endpoint, {
query,
variables,
});
return response.data.data.user;
};Executing Mutations
Mutations modify data on the server and follow the exact same HTTP
transport structure as queries. The mutation string is passed in the
query field of the request payload.
const createUser = async (name, email) => {
const endpoint = 'https://api.example.com/graphql';
const mutation = `
mutation CreateUser($name: String!, $email: String!) {
createUser(input: { name: $name, email: $email }) {
id
name
email
}
}
`;
const variables = {
name,
email,
};
const response = await axios.post(endpoint, {
query: mutation,
variables,
});
return response.data.data.createUser;
};Creating a Reusable Axios Instance
To avoid repeating the endpoint URL and authorization headers in every call, create a dedicated Axios instance:
import axios from 'axios';
const graphqlClient = axios.create({
baseURL: 'https://api.example.com/graphql',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer YOUR_AUTH_TOKEN',
},
});
export const executeGraphQL = async (query, variables = {}) => {
const response = await graphqlClient.post('', {
query,
variables,
});
if (response.data.errors) {
throw new Error(JSON.stringify(response.data.errors));
}
return response.data.data;
};Handling GraphQL Errors
GraphQL handles errors differently than standard REST APIs:
- HTTP-Level Errors (4xx, 5xx): Occur during network
failures or server outages, caught in the standard Axios
catchblock. - GraphQL-Level Errors (200 OK with
errorsarray): When a syntax or execution error occurs within GraphQL, the HTTP status is still usually200 OK. The payload returns anerrorsarray alongside or instead of thedataobject.
Always check for response.data.errors to ensure query
execution succeeded:
const handleRequest = async (query, variables) => {
try {
const response = await axios.post('/graphql', { query, variables });
if (response.data.errors) {
console.error('GraphQL Errors:', response.data.errors);
return null;
}
return response.data.data;
} catch (httpError) {
console.error('HTTP Request Failed:', httpError.message);
}
};