- Introduction
- Getting started
- Philosophy
- Comparison
- Limitations
- Debugging runbook
- FAQ
- Basics
- Concepts
- Network behavior
- Integrations
- API
- CLI
- Best practices
- Recipes
- Cookies
- Query parameters
- Response patching
- Polling
- Streaming
- Network errors
- File uploads
- Responding with binary
- Custom worker script location
- Global response delay
- GraphQL query batching
- Higher-order resolver
- Keeping mocks in sync
- Merging Service Workers
- Mock GraphQL schema
- Remote Request Interception
- Using CDN
- Using custom "homepage" property
- Using local HTTPS
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:
Name | Type | Description |
---|---|---|
query | object | GraphQL query sent from the client. |
variables | object | Variables of this GraphQL query. |
operationName | string | Operation name (e.g. GetUser ). |
request | Request | Entire request reference. |
cookies | object | Request’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 theworker
/server
instance to mark all used request handlers as unused.
Related materials
Describing GraphQL API
Learn about describing GraphQL APIs.