How to mock a REST API for frontend development
The backend endpoint you need does not exist yet, or it is flaky, or you need it to return a 500 so you can test the error state. Waiting is not an option — so you mock it: a stand-in that returns the responses your frontend expects.
This guide compares the main ways to mock an API, from a hosted URL to in-browser interception, and shows how to cover the cases that real APIs make hard to reproduce. To follow along, the free API response mocker turns a list of endpoints into a live URL that any app can call — no sign-up, CORS open.
Why mock an API at all
- Parallel work. Agree on the response shape, mock it, and the frontend ships while the backend is built.
- Edge cases on demand. Empty lists, 401s, 429 rate limits, 500s and slow responses are hard to trigger on a real server and easy to return from a mock.
- Stable demos and tests. A mock never changes data under you, never goes down during a client demo, and never needs credentials.
- Prototypes. A clickable prototype with realistic data convinces stakeholders far better than lorem ipsum.
Four ways to mock: which fits when
1. A hosted mock URL. Define endpoints in a web tool and get a base URL such as https://code.doaide.com/api/mock/abc123. Nothing to install, works from any device, and teammates, Postman or a mobile app can hit the same URL. Best for prototypes, demos, mobile apps and sharing.
2. In-browser interception (MSW). Mock Service Worker intercepts fetch in the browser and Node with handlers written in code. Best when mocks should live in the repo and be reused by unit and end-to-end tests.
3. A local fake server (json-server). Point it at a db.json and get full CRUD that persists to the file. Best when you need writes to stick during a session.
4. Test-level stubs. vi.fn()/jest.fn() replacing fetch, or Playwright’s page.route(). Best for one test that needs one precise response.
Many teams combine them: a hosted mock while the API is being designed, then MSW handlers generated from the agreed contract.
Designing mock responses that catch real bugs
A mock that only returns the happy path hides the bugs you most need to find. For each endpoint, add the variants your UI must handle:
- Status codes — 201 with the created resource, 204 with no body, 400 and 422 with validation errors, 401/403, 404, 409 conflicts, 429 and 500.
- Latency — a 1–3 second delay exposes missing spinners, double-submits and race conditions between requests.
- Shape extremes — empty arrays, very long strings,
nulloptional fields, Unicode names and large pages. - Path parameters —
/users/:idshould echo the id so detail pages show the record you clicked.
GET /users 200 [{"id": 1, "name": "Asha"}, …]
GET /users/:id 200 {"id": "{{id}}", "name": "Asha"}
POST /users 201 {"id": 3} (delay 800 ms)
GET /users/999 404 {"error": "Not found"}
In the API mocker, literal paths take priority over :param ones, so /users/999 can return a 404 while every other id succeeds. Validate the bodies first with the JSON formatter, and generate a schema for them with the JSON Schema generator so the real API can be checked against the same contract later.
Pointing your app at the mock
Keep the base URL in configuration so switching from mock to real API is a one-line change:
# .env.development
VITE_API_URL=https://code.doaide.com/api/mock/abc123
// api.js
const BASE = import.meta.env.VITE_API_URL
export const getUser = (id) => fetch(`${BASE}/users/${id}`).then((r) => r.json())
Hosted mocks must send CORS headers or the browser blocks the response; DoAide’s mocks answer every origin and the OPTIONS preflight, so this works from localhost, a deployed preview or a mobile WebView. Use the copy-curl button to check an endpoint from the terminal first.
Pitfalls: when mocks lie
- Drift. The real API changes and the mock does not. Regenerate mocks from an OpenAPI spec or a schema and run contract tests against the real service.
- Too-perfect data. Real responses have nulls, missing fields and odd casing. Copy a real response into the mock as soon as one exists.
- Secrets. Hosted mocks are reachable by anyone with the URL — never put real customer data or keys in them.
- Forgetting to switch. Log the API base URL at startup in development and fail the production build if it points at a mock.
Frequently asked questions
How do I create a mock API online for free?
Open code.doaide.com/tools/api-mocker, add endpoints with a method, path, status code, optional delay and a JSON body, then press Create mock URL. The base URL is live immediately and works from any app, with CORS enabled.
What is the difference between MSW and a hosted mock API?
MSW intercepts requests inside your app with handlers kept in your codebase, ideal for tests. A hosted mock is a real URL on the internet, so anything — another device, Postman, a teammate or a mobile app — can call it without code changes.
How do I simulate a slow or failing API?
Return the status you want to test (401, 404, 429, 500) from a mock endpoint and add a delay of a few seconds. This exercises loading spinners, retries, timeouts and error messages without touching the real backend.
Can a mock API return different data per id?
Yes. Define the path as /users/:id and put {{id}} in the body to echo the requested id. Add a literal path such as /users/999 to return a specific response, like a 404, for one id.
More guides
- How to review code with AI, free and without sign-up
- How to convert code between languages with AI (Python, Java, JavaScript and more)
- How to generate unit tests with AI: from zero tests to a real suite
- The best free code review tools in 2026
- AI code tools for beginners: learn faster without learning less
- 10 free AI code tools every developer needs in 2026
- DoAide Code: the free alternative to GitHub Copilot
- How to review code with AI for free: workflows that stick
- How to write clean code in 2026
- Best practices for code documentation
- The best free online code formatter in 2026
- Online regex tester and builder: write regular expressions that actually work
- Free online SQL formatter and validator
- Code snippet sharing for developers: stop pasting code into chat
- How to generate a JSON Schema from a JSON sample
- The flexbox cheat sheet: every property and what it actually moves
- Meta tags for SEO: what your pages actually need in 2026
- UUID v4 vs v7: which one should you use?
- CSS Grid explained: tracks, fr, minmax and template areas
- Linux file permissions and chmod, explained
- CSP, CORS and security headers, explained
- YAML, JSON, CSV and XML: converting data and config files safely