Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: deprecate "rest" in favor of "http" #1673

Merged
merged 1 commit into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,11 @@ Let's write an example integration test that asserts the interception of a GET r

```js
// test/browser/example.mocks.ts
import { rest, setupWorker, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'
import { setupWorker } from 'msw/browser'

const worker = setupWorker(
rest.get('/books', () => {
http.get('/books', () => {
return HttpResponse.json([
{
id: 'ea42ffcb-e729-4dd5-bfac-7a5b645cb1da',
Expand Down Expand Up @@ -214,11 +215,11 @@ Let's replicate the same `GET /books` integration test in Node.js.
```ts
// test/node/example.test.ts
import fetch from 'node-fetch'
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'

const server = setupServer(
rest.get('/books', () => {
http.get('/books', () => {
return HttpResponse.json([
{
id: 'ea42ffcb-e729-4dd5-bfac-7a5b645cb1da',
Expand Down
101 changes: 62 additions & 39 deletions MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,29 @@ To help you navigate, we've structured this guide on the feature basis. You can

## Imports

### `rest` becomes `http`

The `rest` request handler namespace has been renamed to `http`.

```diff
-import { rest } from 'msw'
+import { http } from 'msw'
```

This affects the request handlers declaration as well:

```js
import { http } from 'msw'

export const handlers = [
http.get('/resource', resolver),
http.post('/resource', resolver),
http.all('*', resolver),
]
```

### Browser imports

The `setupWorker` API, alongside any related type definitions, are no longer exported from the root of `msw`. Instead, import them from `msw/browser`:

```diff
Expand Down Expand Up @@ -75,7 +98,7 @@ A response resolver now exposes a single object argument instead of `(req, res,
To mock responses, you should now return a Fetch API `Response` instance from the response resolver. You no longer need to compose a response via `res()`, and all the context utilities have also [been removed](#context-utilities).

```js
rest.get('/greet/:name', ({ request, params }) => {
http.get('/greet/:name', ({ request, params }) => {
console.log('Captured %s %s', request.method, request.url)
return new Response(`hello, ${params.name}!`)
})
Expand All @@ -84,10 +107,10 @@ rest.get('/greet/:name', ({ request, params }) => {
Now, a more complex example for both REST and GraphQL requests.

```js
import { rest, graphql } from 'msw'
import { http, graphql } from 'msw'

export const handlers = [
rest.put('/user/:id', async ({ request, params, cookies }) => {
http.put('/user/:id', async ({ request, params, cookies }) => {
// Read request body as you'd normally do with Fetch.
const payload = await request.json()
// Access path parameters like before.
Expand Down Expand Up @@ -127,7 +150,7 @@ Since the returned `request` is now an instance of Fetch API `Request`, there ar
The `request.url` property is a string (previously, a `URL` instance). If you wish to operate with it like a `URL`, you need to construct it manually:

```js
rest.get('/product', ({ request }) => {
http.get('/product', ({ request }) => {
// For example, this is how you would access
// request search parameters now.
const url = new URL(request.url)
Expand All @@ -140,7 +163,7 @@ rest.get('/product', ({ request }) => {
Path parameters are now exposed directly on the [Resolver info](#resolver-info) object (previously, `req.params`).

```js
rest.get('/resource', ({ params }) => {
http.get('/resource', ({ params }) => {
console.log('Request path parameters:', params)
})
```
Expand All @@ -150,7 +173,7 @@ rest.get('/resource', ({ params }) => {
Request cookies are now exposed directly on the [Resolver info](#resolver-info) object (previously, `req.cookies`).

```js
rest.get('/resource', ({ cookies }) => {
http.get('/resource', ({ cookies }) => {
console.log('Request cookies:', cookies)
})
```
Expand All @@ -164,7 +187,7 @@ The library now does no assumptions when reading the intercepted request's body
For example, this is how you would read request body:

```js
rest.post('/resource', async ({ request }) => {
http.post('/resource', async ({ request }) => {
const data = await request.json()
// request.formData() / request.arrayBuffer() / etc.
})
Expand All @@ -175,10 +198,10 @@ rest.post('/resource', async ({ request }) => {
Using the Fetch API `Response` instance may get quite verbose. To give you more convenient means of declaring mocked responses while remaining specification compliant and compatible, the library now exports an `HttpResponse` object. You can use that object to construct response instances faster.

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/user', () => {
http.get('/user', () => {
// This is synonymous to "ctx.json()":
// HttpResponse.json() stringifies the given body
// and sets the correct "Content-Type" response header
Expand All @@ -197,10 +220,10 @@ Although MSW now respects the Fetch API specification, the older versions of Nod
To account for this, the library exports a `Response` class that you should use when declaring request handlers. Behind the hood, that response class is resolved to a compatible polyfill in Node.js; in the browser, it only aliases `global.Response` without introducing additional behaviors.

```js
import { rest, Response } from 'msw'
import { http,Response } from 'msw'

setupServer(
rest.get('/ping', () => {
http.get('/ping', () => {
return new Response('hello world)
})
)
Expand All @@ -216,7 +239,7 @@ To create a one-time request handler, pass it an object as the third argument wi
import { HttpResponse, rest } from 'msw'

export const handlers = [
rest.get(
http.get(
'/user',
() => {
return HttpResponse.text('hello')
Expand All @@ -229,10 +252,10 @@ export const handlers = [
## `req.passthrough`

```js
import { rest, passthrough } from 'msw'
import { http, passthrough } from 'msw'

export const handlers = [
rest.get('/user', () => {
http.get('/user', () => {
// Previously, "req.passthrough()".
return passthrough()
}),
Expand All @@ -249,7 +272,7 @@ Most of the context utilities you'd normally use via `ctx.*` were removed. Inste
import { HttpResponse, rest } from 'msw'

export const handlers = [
rest.post('/user', () => {
http.post('/user', () => {
// ctx.json()
return HttpResponse.json(
{ firstName: 'John' },
Expand All @@ -269,10 +292,10 @@ Let's go through each previously existing context utility and see how to declare
### `ctx.status`

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.text('hello', { status: 201 })
}),
]
Expand All @@ -281,10 +304,10 @@ export const handlers = [
### `ctx.set`

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.text('hello', {
headers: {
'Content-Type': 'text/plain; charset=windows-1252',
Expand All @@ -300,7 +323,7 @@ export const handlers = [
import { HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.text('hello', {
headers: {
'Set-Cookie': 'token=abc-123',
Expand All @@ -316,7 +339,7 @@ When you provide an object as the `ResponseInit.headers` value, you cannot speci
import { Headers, HttpResponse, rest } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return new HttpResponse(null, {
headers: new Headers([
// Mock a multi-value response cookie header.
Expand All @@ -333,10 +356,10 @@ export const handlers = [
### `ctx.body`

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return new HttpResponse('any-body')
}),
]
Expand All @@ -347,10 +370,10 @@ export const handlers = [
### `ctx.text`

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.text('hello')
}),
]
Expand All @@ -359,10 +382,10 @@ export const handlers = [
### `ctx.json`

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.json({ firstName: 'John' })
}),
]
Expand All @@ -371,10 +394,10 @@ export const handlers = [
### `ctx.xml`

```js
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.xml('<user id="abc-123" />')
}),
]
Expand All @@ -388,7 +411,7 @@ The `ctx.data` utility has been removed in favor of constructing a mocked JSON r
import { HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.json({
data: {
user: {
Expand All @@ -408,7 +431,7 @@ The `ctx.errors` utility has been removed in favor of constructing a mocked JSON
import { HttpResponse } from 'msw'

export const handlers = [
rest.get('/resource', () => {
http.get('/resource', () => {
return HttpResponse.json({
errors: [
{
Expand All @@ -423,10 +446,10 @@ export const handlers = [
### `ctx.delay`

```js
import { rest, HttpResponse, delay } from 'msw'
import { http, HttpResponse, delay } from 'msw'

export const handlers = [
rest.get('/resource', async () => {
http.get('/resource', async () => {
await delay()
return HttpResponse.text('hello')
}),
Expand All @@ -445,10 +468,10 @@ await delay('infinite')
The `ctx.fetch()` function has been removed in favor of the `bypass()` function. You should now always perform a regular `fetch()` call and wrap the request in the `bypass()` function if you wish for it to ignore any otherwise matching request handlers.

```js
import { rest, HttpResponse, bypass } from 'msw'
import { http, HttpResponse, bypass } from 'msw'

export const handlers = [
rest.get('/resource', async ({ request }) => {
http.get('/resource', async ({ request }) => {
const fetchArgs = await bypass(request)

// Use the regular "fetch" from your environment.
Expand Down Expand Up @@ -553,7 +576,7 @@ import { rest } from 'msw'
import { augmentResponse } from './utils'

export const handlers = [
rest.get('/user', () => {
http.get('/user', () => {
return augmentResponse({ id: 1 })
}),
]
Expand All @@ -579,7 +602,7 @@ For example, this is how you would read the request as `Blob`:
import { rest } from 'msw'

export const handlers = [
rest.get('/resource', async ({ request }) => {
http.get('/resource', async ({ request }) => {
const blob = await request.blob()
}),
]
Expand All @@ -590,9 +613,9 @@ export const handlers = [
You can now send a `ReadableStream` as the mocked response body. This is great for mocking any kind of streaming in HTTP responses.

```js
import { rest, HttpResponse, ReadableStream, delay } from 'msw'
import { http, HttpResponse, ReadableStream, delay } from 'msw'

rest.get('/greeting', () => {
http.get('/greeting', () => {
const encoder = new TextEncoder()
const stream = new ReadableStream({
async start(controller) {
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ In-browser usage is what sets Mock Service Worker apart from other tools. Utiliz
```js
// src/mocks.js
// 1. Import the library.
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'
import { setupWorker } from 'msw/browser'

// 2. Describe network behavior with request handlers.
const worker = setupWorker(
rest.get('https://github.com/octocat', ({ request, params, cookies }) => {
http.get('https://github.com/octocat', ({ request, params, cookies }) => {
return HttpResponse.json(
{
message: 'Mocked response',
Expand Down Expand Up @@ -121,7 +121,7 @@ Take a look at the example of an integration test in Jest that uses [React Testi
// test/Dashboard.test.js

import React from 'react'
import { rest, HttpResponse } from 'msw'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { render, screen, waitFor } from '@testing-library/react'
import Dashboard from '../src/components/Dashboard'
Expand All @@ -130,7 +130,7 @@ const server = setupServer(
// Describe network behavior with request handlers.
// Tip: move the handlers into their own module and
// import it across your browser and Node.js setups!
rest.get('/posts', ({ request, params, cookies }) => {
http.get('/posts', ({ request, params, cookies }) => {
return HttpResponse.json([
{
id: 'f8dd058f-9006-4174-8d49-e3086bc39c21',
Expand Down
Loading
Loading