graphql

Intercept GraphQL API requests.

The graphql namespace helps you create request handlers to intercept requests to a GraphQL API.

Call signature

graphql.query<Query, Variables>(
  query: string | RegExp | DocumentNode | TypedDocumentNode,
  resolver: ResponseResolver<
    GraphQLResolverExtras<Variables>,
    null,
    GraphQLResponseBody<Query>
  >,
  options?: RequestHandlerOptions
)

graphql.ts

Source code for the `graphql` namespace.

Standard methods

The graphql namespace contains keys that represent GraphQL operation types (e.g. “query”, “mutation”).

graphql.query(queryName, resolver)

import { graphql, HttpResponse } from 'msw'
 
export const handlers = [
  graphql.query('GetUser', ({ query, variables }) => {
    const { userId } = variables
 
    return HttpResponse.json({
      data: {
        user: {
          name: 'John',
        },
      },
    })
  }),
]

The handler above will intercept and mock the response to the following GraphQL query:

query GetUser($userId: String!) {
  user(id: $userId) {
    name
  }
}

The queryName argument can also be a TypedDocumentNode instance. This means you can pass the generated document types based on your GraphQL operations directly to MSW when using tools like GraphQL Code Generator.

import { graphql, HttpResponse } from 'msw'
import { GetUserDocument } from './generated/types'
 
graphql.query(GetUserDocument, ({ query, variables }) => {
  return HttpResponse.json({
    data: {
      user: {
        id: '75a22f38-c27c-4684-9bdf-d4b16435af1a',
        name: 'John',
      },
    },
  })
})

MSW will infer the query and variable types from the given document node.

graphql.mutation(mutationName, resolver)

import { graphql, HttpResponse } from 'msw'
 
export const handlers = [
  graphql.mutation('CreateUser', ({ query, variables }) => {
    const { input } = variables
 
    return HttpResponse.json({
      data: {
        user: {
          name: input.name,
        },
      },
    })
  }),
]

The handler above will intercept and mock the response to the following GraphQL mutation:

mutation CreateUser($userInput: CreateUserInput!) {
  createUser(input: $userInput) {
    name
  }
}

The mutationName argument can also be a TypedDocumentNode instance. This means you can pass the generated document types based on your GraphQL operations directly to MSW when using tools like GraphQL Code Generator.

import { graphql, HttpResponse } from 'msw'
import { CreateUserDocument } from './generated/types'
 
graphql.mutation(CreateUserDocument, ({ variables }) => {
  return HttpResponse.json({
    data: {
      user: {
        name: variables.input.name,
      },
    },
  })
})

Custom methods

The graphql namespace also contains special keys that provide you with additional functionality but do not correspond to any GraphQL operation types.

graphql.link(url)

The .link() method returns a subset of the graphql namespace to intercept GraphQL operations scoped to the provided endpoint. You can use this method to disambiguate between GraphQL operations.

import { graphql, HttpResponse } from 'msw'
 
const github = graphql.link('https://api.github.com/graphql')
const stripe = graphql.link('https://api.stripe.com/graphql')
 
export const handlers = [
  github.query('GetPayment', () => {
    return HttpResponse.json({
      data: {
        payment: {
          id: 'e16fded7-64eb-4b69-b4bd-5345507a5a92',
          issuer: { login: 'octocat' },
        },
      },
    })
  }),
  stripe.query('GetPayment', () => {
    return HttpResponse.json({
      errors: [{ message: 'Cannot process payment' }],
    })
  }),
]

Although the name of the GetPayment query is the same, it will be handled differently depending on the requested endpoint.

graphql.operation(resolver)

The .operation() method intercepts all GraphQL operations regardless of their type and name. It’s designed to cover the following scenarios:

  • Handling of anonymous GraphQL operations;
  • Resolving any outgoing GraphQL operations against a mock GraphQL schema.
import { graphql, HttpResponse } from 'msw'
 
export const handlers = [
  graphql.operation(({ query, variables }) => {
    // Intercept all GraphQL operations and respond
    // to them with the error response.
    return HttpResponse.json({
      errors: [{ message: 'Request failed' }],
    })
  }),
]

Resolver argument

The response resolver function for every graphql.* method has the following keys in its argument object:

NameTypeDescription
queryobjectGraphQL query sent from the client.
variablesobjectVariables of this GraphQL query.
operationNamestringOperation name (e.g. GetUser).
requestRequestEntire request reference.
cookiesobjectRequest’s cookies.

You access these arguments on the response resolver argument object.

graphql.query('GetUser', ({ query, variables, operationName, request }) => {})

Handler options

All methods of the http namespace accept an optional third argument representing request handler options. See below for the list of supported properties on that options object.

once

  • boolean

If set to true, marks this request handler as used after the first successful match. Used request handlers have no effect on the outgoing traffic and will be ignored during request interception.

graphql.query(
  'GetUser',
  () => {
    return HttpResponse.json({
      data: {
        user: { name: 'John' },
      },
    })
  },
  {
    once: true,
  }
)

Use the .restoreHandlers() method on the worker/server instance to mark all used request handlers as unused.

Describing GraphQL API

Learn about describing GraphQL APIs.