Spawn an HTTP server from your Mock Service Worker request handlers.
Tags: javascript, testing, api, backend
Published: 2021-07-23 15:50:15

When [Mock Service Worker](https://mswjs.io/) was released, it had a clear mission to enable API mocking without the need to spawn and maintain an actual HTTP server. This purposeful restriction, among a few other core principles, has led to thousands of developers writing declarative, agnostic, and reusable mocks every day, prototyping amazing applications and delivering stunning products with confidence.

While our "you don't need a mocking server" principle still stands strong today, we listen closely and analyze all the great feedback that our users share with us in order to improve the project and increase the amount of use cases it could cover.

Today, I'm excited to tell you about a project that [David Idol](https://github.com/idolize) and I have collaborated on with a goal to bring Mock Service Worker to more challenging usage contexts. We named it "http-middleware".

{% github mswjs/http-middleware no-readme %}

---

## The Concept

The premise of `http-middleware` is extremely straightforward: _reuse your request handlers to create an actual HTTP server_.

This project is designed to cover more complex use cases when the standard Mock Service Worker approach isn't sufficient. Such use cases include:

- Adding the ability to `curl` your mock definitions, for example, for local debugging;
- Integrating API mocking in complex application architecture (i.e. with dockerized apps).
- Prototyping Node.js server development.

Note that this project is **not a go-to solution for API mocking**, and you should always favor Mock Service Worker instead. It's created to handle complex use cases and you'd know when you need it. As a rule of thumb: when in doubt, prefer MSW.

**Learn more about how to [get started with MSW](https://mswjs.io/docs/getting-started/install)**. 

---

## The Usage

The "http-middleware" project is so concise that I've decided to write a brief usage tutorial right here, right now. Let's get a server running in 2 minutes with your request handlers being the source of truth.

First, create a project if you don't have one already:

```sh
$ npm init -y
```

Then, install the necessary dependencies:

```sh
$ npm install express msw @mswjs/http-middleware --save-dev
```

To keep things simple, let's have a single `server.js` file where we will declare our server:

```sh
$ touch server.js
```

Finally, use the `createServer` function to spawn an [Express](https://expressjs.com/) server. Provide it with the request handlers you want to be responsible for producing responses:

```js
// server.js
const { rest } = require('msw')
const { createServer } = require('@mswjs/http-middleware')

const httpServer = createServer(
  rest.get('/', (req, res, ctx) => {
    return res(ctx.text('Hello world'))
  })
)

httpServer.listen(9090)
```

> Learn more about writing [request handlers](https://mswjs.io/docs/getting-started/mocks) with Mock Service Worker. You can reuse the _same_ handlers you write in tests, local development, and debugging.

Now run your server:

```sh
$ node server.js
```

Try making a `GET http://localhost:9090` request. You'll see that the response was resolved based on the request handler you've specified:

```json
200 OK
Content-Type: text/plain;

"Hello world"
```

Done 🎉

### Adding to an existing server

Alternatively, you can apply request handlers via a middleware, which is handy in case you already have a server:

```js
// existing-server.js
import { rest } from 'msw'
import { createMiddleware } from '@mswjs/http-middleware'
import { app } from './app'

app.use(
  createMiddleware(
    rest.get('/', (req, res, ctx) => {
      return res(ctx.text('Hello world'))
    })
  )
)
```

---

## The Cherry on Top

With request handlers acting as the source of truth, you get the same benefits as when using MSW: _shared API mocking logic_ across different environments and purposes.

I can't stress enough how important it is to have a clean, deterministic testing setup. There is absolutely no reason to install 3 different libraries for API mocking just because you want to mock the same API in an integration test, and then in an end-to-end test, and then to debug an irksome data-driven bug.

Mock Service Worker allows you to write your API mocks ***once*** and reuse them _anywhere_ later: when working on the app, when testing it in Node.js, when running automated tests in Cypress, when debugging. All that using the same familiar consistent syntax. Don't miss out.

{% github mswjs/msw no-readme %}

### Embrace the ecosystem

By leveraging libraries like [@mswjs/data](https://github.com/mswjs/data), you can have data-driven type-safe API mocking reused across the _entire stack_. Develop and iterate on your next product with the speed of light by the flexibility Mock Service Worker and its ecosystem gives you.

---

## Afterword

We're excited to see what impact this small package will have in your development workflow! Make sure to [**follow Mock Service Worker on Twitter**](https://twitter.com/ApiMocking) to get the latest news and be notified about many upcoming features. 

We also highly encourage you to contribute to the `http-middleware` package with your ideas and feedback on GitHub:

{% github mswjs/http-middleware no-readme %}

Stay awesome ❤️