Skip to content

Commit

Permalink
feat: deprecate "rest" in favor of "http" (#1673)
Browse files Browse the repository at this point in the history
  • Loading branch information
kettanaito committed Jul 31, 2023
1 parent 61f6f3b commit c371f03
Show file tree
Hide file tree
Showing 136 changed files with 2,458 additions and 2,523 deletions.
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

0 comments on commit c371f03

Please sign in to comment.