There's a good chance you've been in this situation as a frontend developer: you've been tasked with building a shiny new feature, but the API endpoints you need have not yet been created.
Whilst it is possible to emulate intended behaviour - wiring up API endpoints later on is usually cumbersome and unappealing.
Mock Service Worker to the Rescue!
MSW is a library that can mock API endpoints at the network level. This means we can build components as if API endpoints already exist, with our app and browser not knowing any different.
Add MSW to your project
yarn add msw --dev
Use the CLI to add the service worker to your server's public folder. In this example I am using Create React App.
npx msw init public/ --save
Define handlers and setup the worker. Here we are telling MSW to mock a GET request to /user
, responding with an object containing username: admin
.
// src/mocks/browser.js
import {rest, setupWorker} from 'msw'
const handlers = [
rest.get('/user', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
username: 'admin',
}),
)
}),
]
export const worker = setupWorker(...handlers)
Start the worker with your app
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
if (process.env.NODE_ENV === 'development') {
const { worker } = require('./mocks/browser')
worker.start()
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Now when starting your app, you should see the message "[MSW] Mocking enabled" in the browser console; meaning we are good to go!
Using our mocked data
Let's create a basic component that can use our newly mocked endpoint.
Define state to store our username
const [username, setUsername] = useState();
Add a fetch call on component mount
const fetchUser = async () => {
const response = await fetch('/user');
const data = await response.json();
setUsername(data.username);
}
useEffect(() => {
fetchUser().catch(console.error);
},[])
If we have the username defined in state, return a greeting, otherwise return a loading message.
if(username){
return <h1>{`Hello, ${username}!`}</h1>
}
return "Loading..."
You should now see this when running your app:
Hopefully this basic example shows the ease of integrating MSW into React apps, and how it reduces dependency on others whilst developing.
Top comments (2)
I prefer to have Open API Specification ready, and load it in Mockoon.
What a blast it'd be if MSW supported Open API-based request handlers. Maybe one day it will. Your setup looks like a decent choice though!