Guide to Mocking API with MSW in NextJS
Introduction
MSW (Mock Service Worker) is the most popular library for modern projects, used to simulate APIs by intercepting network requests at the network layer. Instead of mocking at the application layer, MSW operates at the Service Worker layer (browser) and Node.js interception (server-side).
Advantages:
- Simulate everything: Method, URL, Header, Status code, Delay.
- Help Frontend develop independently when Backend has not finished the API.
- Runs on both the browser (Browser) and NodeJS environment (SSR).
- Does not change the API call logic code, only needs request interception configuration.
- Clean mock code, written like writing a real API.
Usage: You define handlers. When the application calls a URL, MSW catches that request and returns the response you defined without ever actually sending the request to the server.
Detail
Run the following commands to install and create the mockServiceWorker.js file
Add the following values to the .env file
Because this is just a simulation, it only needs to run on the dev environment, you should configure it like this to easily disable it when deploying to production
Create file mock/handlers.ts
- This code defines "handlers" to handle HTTP requests (GET, POST, PUT, DELETE). It uses a `products` array as a mock database in memory to perform CRUD operations (Create, Read, Update, Delete) like a real API, along with a `delay` effect to simulate network latency.
- After starting the project, you can view the logs on NextJS to check that the /products api will be called on the server first and then return data to the client
Create file mock/browser.ts
Create file mock/node.ts
Create file mock/MSWProvider.tsx
- This is the Provider component used to initialize MSW on the browser. It checks if the environment is `dev` then activates the Service Worker to intercept requests from the client-side. The `mswReady` state ensures the application only renders when MSW is ready to operate.
- onUnhandledRequest: 'bypass' helps real requests (not mocked) still run normally
Create file provider/react-query.tsx
- Initialize QueryClient in useState to ensure each instance is unique and not re-initialized every time the component re-renders.
- staleTime: 60 * 1000, data is considered fresh for 1 minute
Update file app/layout.tsx
- This is the main layout file of NextJS. Here, we activate MSW Server for the backend (SSR) via `server.listen()`. At the same time, the Providers (MSW, React Query) are wrapped around the website content to provide corresponding features for the entire application.
- server.listen() only runs once on the NodeJS side
- We check NEXT_RUNTIME is a special environment variable to make sure not to call it wrong in Edge Runtime or Client side
Create file app/msw/actions.ts
Create file app/msw/page.tsx
This file acts as a Server Component. It initializes a temporary `QueryClient` to prefetch data on the server. It then uses `HydrationBoundary` to "pass" this fetched data down to the Client Component, helping the website display data immediately without waiting for the client to fetch again.
Create file app/msw/ProductPage.tsx
This is a complete product management interface, it uses `useQuery` to display the product list (receiving data from the previous server-side cache) and `useMutation` to handle adding, editing, and deleting products. All actions are intercepted by MSW and processed locally without the need for a real API.
The result when you view API information in the Network tab will show a notification from service worker
Happy coding!
Comments
Post a Comment