DEV Community

loading...
Cover image for Spawn an HTTP server from your Mock Service Worker request handlers.

Spawn an HTTP server from your Mock Service Worker request handlers.

Artem Zakharchenko
JavaScript engineer, passionate about open source, UI, and modern web development.
・4 min read

When Mock Service Worker 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 and I have collaborated on with a goal to bring Mock Service Worker to more challenging usage contexts. We named it "http-middleware".

GitHub logo mswjs / http-middleware

Spawn an HTTP server from your request handlers or apply them to an existing server using a middleware.


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.


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:

$ npm init -y
Enter fullscreen mode Exit fullscreen mode

Then, install the necessary dependencies:

$ npm install express msw @mswjs/http-middleware --save-dev
Enter fullscreen mode Exit fullscreen mode

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

$ touch server.js
Enter fullscreen mode Exit fullscreen mode

Finally, use the createServer function to spawn an Express server. Provide it with the request handlers you want to be responsible for producing responses:

// 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)
Enter fullscreen mode Exit fullscreen mode

Learn more about writing request handlers with Mock Service Worker. You can reuse the same handlers you write in tests, local development, and debugging.

Now run your server:

$ node server.js
Enter fullscreen mode Exit fullscreen mode

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

200 OK
Content-Type: text/plain;

"Hello world"
Enter fullscreen mode Exit fullscreen mode

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:

// 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'))
    })
  )
)
Enter fullscreen mode Exit fullscreen mode

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 logo mswjs / msw

Seamless REST/GraphQL API mocking library for browser and Node.js.

Embrace the ecosystem

By leveraging libraries like @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 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 logo mswjs / http-middleware

Spawn an HTTP server from your request handlers or apply them to an existing server using a middleware.

Stay awesome ❤️

Discussion (0)