Intercepting GraphQL operations

On the web, GraphQL APIs are often implemented over HTTP. This means that, technically, you can still use the http namespace to intercept your GraphQL operations as regular HTTP requests. However, it is recommended to use the designated graphql namespace instead, as it provides a better developer experience and a richer feature-set when it comes to working with GraphQL.

This page will walk you through the possible ways to intercept a GraphQL operation with MSW.

Endpoint-first mocking

By default, the library ignores the server sendpoint when matching GraphQL operations. That is a conscious decision since it is rare that a single application would interact with multiple GraphQL APIs. It means that the same handler will match a GetUser operation even if one is sent to /api/graphql and the other to https://api.example.com.

This default is supported for backward-compatibility, but it is strongly recommended to use graphql.link() to scope GraphQL mocking to a particular server endpoint.

import { graphql } 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('GetUser', oneResolver),
  stripe.query('GetUser', anotherResolver),
]

By defining GraphQL links, you tell MSW to take the server endpoint into account when performing operation matching.

Operation kind

The library supports intercepting GraphQL queries and mutations (subscriptions support coming soon). Learn more about intercepting the operation kind you need:

You can also intercept any GraphQL operation regardless of its kind, which is handy in ambiguous contexts. Learn more about that approach on this page:

Operations

Learn about interceping any GraphQL operation

Predicate

Named operations

It is not required but strongly recommended to use named GraphQL operations when working with the library. Named operations will allow for easier interception since GraphQL mocking in MSW is operation-based and not field-based by default.

# The following GraphQL query can be handled
# with a handler that looks like this:
#
# graphql.query('GetUser', resolver)
query GetUser {
  user {
    id
  }
}

You can opt to use field-based mocking by following the Schema-first mocking recipe. Combining the two is also an option!

Operation name

You can provide a string as a request handler predicate that represents the name of the GraphQL operation you wish to intercept.

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

This handler will match the following GraphQL query:

query GetUser {
  user { ... }
}

The same is true for mutations, just don’t forget to use graphql.mutation() instead.

Regular expression

You can provide a regular expression as a request handler predicate. MSW will test the outgoing operation names against that expression to determine if they match.

graphql.mutation(/user/i, () => {})

This handler will match both CreateUser and UpdateUser mutations.

Response resolver

The following properties are available on the response resolver object argument for graphql.* handlers:

PropertyTypeDescription
cookiesRecord<string, string>Parsed requets cookies.
querystringRaw GraphQL query string.
variablesRecord<string, any>Parsed variables of this operation.
operationNamestringOperation name (e.g. 'GetUser').
graphql.mutation(
  'UpdateUser',
  ({ cookies, query, variables, operationName }) => {},
)

Next steps

Now that you know how to intercept GraphQL operations, proceed by learning how to handle their responses:

Mocking responses

Different ways to handle an intercepted GraphQL operation.