Help build the future of open source observability software Open positions

Check out the open source projects we support Downloads

We cannot remember your choice unless you click the consent notice at the bottom.

How to load test GraphQL

How to load test GraphQL

2019-09-19 4 min

This content was originally published on k6.io.
30 Jan 2024

The popularity and adoption of GraphQL have been impressive over the past few years, and as more users start discovering Grafana k6, we are getting more questions about GraphQL. This post provides some useful information for those beginning with k6 to test a GraphQL service.

Does k6 support load testing GraphQL?

The short answer is yes! k6 supports load testing GraphQL services running over HTTP or WebSocket.

But I’d like to elaborate more on this answer because we’ve found some users were slightly confused about how GraphQL or k6 works.

GraphQL is a transport agnostic “language.”

GraphQL is a language for querying and manipulation of APIs; the specification defines the syntax to communicate with a GraphQL API.

For example, given an API schema like:

type Query {
  me: User
}

type User {
  id: ID
  name: String
}

The query will be:

{
  me {
    name
  }
}

GraphQL is transport-layer agnostic; it does not restrict a GraphQL server to run over a particular transport protocol. HTTP is the common choice because of its ubiquity, but a GraphQL server could run over different protocols like:

  • HTTP, AMQP, Websockets
  • Low level-protocols: TCP, UDP, gRPC

On the other side, k6, which takes the role of the GraphQL client, can generate requests over HTTP or Websocket at the time of writing this post. This means that k6 can load test any GraphQL server that runs over one of the supported k6 protocols.

Testing the GitHub GraphQL API

Let’s show an example using k6 to test a GraphQL service. To avoid setting up and running our own GraphQL server, we will load test the GitHub GraphQL API. We chose the GitHub API because it is familiar to developers, well-documented, and has multiple schema types, queries, and mutations.

To start, we need a Personal GitHub Token to authenticate with the GitHub API. Follow this GitHub guide to create a Personal Token for running this test. Depending on the requests of our test, your token will need different permissions or scopes. For the next example, your token needs the following permissions:

  • Access public repositories: repo:public_repo
  • Read and write team discussions: write:discussion

How do I create my first GraphQL request?

Because the GitHub GraphQL API runs over HTTP, and the GraphQL queries or mutations requires a JSON-encoded body, you will use the http.post function to generate requests to hit the API.

We’ll start our test by getting some data from the GitHub API.

What was the first GitHub issue of the k6 project?

The code is quite simple; you only have to set your Token on the Authorization header, write the GraphQL query (Object/Repository/Issues), and send it on the POST request.

JavaScript
const accessToken = 'YOUR_GITHUB_ACCESS_TOKEN';

const query = `
 query FindFirstIssue {
   repository(owner:"grafana", name:"k6") {
     issues(first:1) {
       edges {
         node {
           id
           number
           title
         }
       }
     }
   }
 }`;

const headers = {
  'Authorization': `Bearer ${accessToken}`,
  'Content-Type': 'application/json',
};

const res = http.post('https://api.github.com/graphql', JSON.stringify({ query: query }), {
  headers: headers,
});

Right now, our k6 script is just hitting the endpoint to always request the same data, but we wanted to create a test to replicate a particular user interaction.

How to debug the response data

While developing your script, you might want to see the response data to validate the data or use it in your load test.

JavaScript
if (res.status === 200) {
  console.log(JSON.stringify(res.body));
  const body = JSON.parse(res.body);
  const issue = body.data.repository.issues.edges[0].node;
  console.log(issue.id, issue.number, issue.title);
}

The output will be something like:

INFO[0001] "{"data":{"repository":{"issues":{"edges":[{"node":{"id":"MDU6SXNzdWUxNzA0MzczOTY=","number":4,"title":"Deduplicate HTTP client code"}}]}}}}"
INFO[0001] MDU6SXNzdWUxNzA0MzczOTY=                      0=4 1="Deduplicate HTTP client code"

Run a mutation to add a 🎉 reaction to the first k6 issue

This simple example intends to show how to update server data based on data fetched from another request. In GraphQL, you will use mutations to modify data.

You can read the addReaction docs or find examples to learn the syntax of this mutation. In this case, the addReaction mutation needs the issue.id to add the 🎉 reaction to the issue. Below is what it looks like:

JavaScript
const mutation = `
  mutation AddReactionToIssue {
    addReaction(input:{subjectId:"${issue.id}",content:HOORAY}) {
      reaction {
        content
      }
      subject {
        id
      }
    }
}`;

res = http.post('https://api.github.com/graphql', JSON.stringify({ query: mutation }), {
  headers: headers,
});

Now, you can run the test and check out the reaction to the k6 issue by hovering over 🎉. Check out the full example in GitHub.

Conclusion

Testing GraphQL with k6 is as simple as generating a request with data. While this blog includes a basic example to provide you with a starting point for testing a GraphQL service with k6, the k6 script and k6 options give you the chance to run a wide range of performance tests for a GraphQL service.