- 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
Response resolver
Response resolver is a function that controls how to handle (resolve) the intercepted request.
For example, this is how you would respond with a 200 OK Hello World!
response to a GET /greeting
request:
import { http, HttpResponse } from 'msw'
export const handlers = [
// Describe what request to intercept...
http.get('/greeting', () => {
// ...and how to respond to it.
return new HttpResponse('Hello world!')
}),
]
Arguments
Response resolver provides you with a single argument, which is an object containing a bunch of information about the intercepted request.
http.post('/post/:postId', async ({ request, params, cookies }) => {
const { postId } = params
const requestBody = await request.json()
})
Common arguments
The data below is available for every intercepted request, regardless if it’s a REST API or a GraphQL request.
Name | Type | Description |
---|---|---|
request | Request | Fetch API Request representation of the intercepted request. |
requestId | string | A UUID string identifier for the intercepted request. |
cookies | Record<string, string> | Request cookies. |
params | Record<string, string[] | string> | Request path parameters. |
Here’s an example of how to access the intercepted request path parameters in the response resolver:
http.get('/post/:postId', ({ params }) => {
const { postId } = params
})
GraphQL Arguments
The data below is only available for GraphQL requests.
Name | Type | Description |
---|---|---|
query | string | GraphQL query string. |
variables | Record<string, unknown> | Variables of the intercepted query. |
operationName | string | GraphQL operation name (e.g. GetUser ). |
Here’s an example of how to access GraphQL variables in the response resolver:
import { graphql, HttpResponse } from 'msw'
export const handlers = [
graphql.query('GetUser', ({ variables }) => {
const { userId } = variables
return HttpResponse.json({
data: {
user: {
id: userId,
},
},
})
}),
]
Resolver instructions
Response resolver must always return the instruction on what to do with the intercepted request. There are the following instructions possible:
Respond with a mocked response
To respond to an intercepted request with a mocked response, construct a Fetch API Response
instance and return it from the response resolver.
import { http } from 'msw'
export const handlers = [
http.get('/post/:id', ({ params }) => {
return Response.json({
id: params.id,
title: 'Hello world',
})
}),
]
You don’t have to import the
Response
constructor because it’s a part of the standard Fetch API available in every browser and in modern versions of Node.js (v18.0.0+).
For better compatibility, we highly recommend using the HttpResponse
class from MSW instead of the native Response
:
HttpResponse
API reference for the `HttpResponse` class.
Passthrough the request
To passthrough the intercepted request (perform it as-is), return the passthrough()
function call from the response resolver.
import { http, passthrough } from 'msw'
export const handlers = [
http.get('/user', () => {
return passthrough()
}),
]
passthrough
Handle the intercepted request by performing it as-is.
Fallthrough the request
If a response resolver returns nothing, it stops execution and tells MSW to keep looking for any other matching request handlers that may return instruction on how to handle the intercepted request.
import { http, HttpResponse } from 'msw'
export const handlers = [
http.get('/user', ({ request }) => {
// If the intercepted request has a particular
// "Accept" header value, skip this request handler
// and let MSW "fallthrough" to the next one.
if (request.headers.get('Accept') === 'text/csv') {
return
}
return HttpResponse.json({ name: 'John' })
}),
http.get('/user', () => {
// Since this request handler also matches the
// "GET /user" request, it will be used instead
// when the "Accept" request header is "text/csv".
return HttpResponse.text('John')
}),
]
Combining instructions
A single response resolver may handle the intercepted request differently based on a certain criteria.
For example, here’s how you can respond with a mocked response only when the path parameter satisfies a certain condition, and passthrough the request if it doesn’t:
import { http, HttpResponse, passthrough } from 'msw'
export const handlers = [
http.get('/user/:id', ({ params }) => {
const { id } = params
// Return a mocked response only when
// requesting "GET /user/abc-123".
if (id === 'abc-123') {
return HttpResponse.json({
id,
name: 'John',
})
}
// Otherwise, perform the request as-is.
return passthrough()
}),
]