Your app already calls the API. What you need now is the other half: the 404, the 500, the empty list — without asking anyone to break staging, and without if (mock) in the client.
In this article you’ll:
- Define several named responses on the same endpoint
- Pick which one is active with a single JSON key
- Hit the same URL with
curland get 200, 404, or 500
The frontend keeps the same base URL (http://localhost:3001). You only edit the mock file.
This is a CLI (mock-server), not an embeddable SDK.
Prerequisites
- Node.js >= 22.12
- A project with a
package.json(recommended)
Setup
npm install http-mock-json --save-dev
npx mock-server init
npx mock-server start
init creates mocks/, adds a mock:start script, and can scaffold a first file. The server listens on port 3001. Watch mode is always on: save a mock and it reloads.
If you already have the server running, skip this section and open your JSON.
One endpoint, several scenarios
Each HTTP method has two pieces:
| Piece | Role |
|---|---|
responses |
Named scenarios (name, statusCode, body) |
nameResponse |
Which scenario is returned |
The URL does not change. Only nameResponse does.
Open mocks/animals.json (or create it) and use this:
{
"data/animals": {
"GET": {
"nameResponse": "success",
"responses": [
{
"name": "success",
"statusCode": "200",
"body": {
"animals": [
{ "id": 1, "name": "Lion" },
{ "id": 2, "name": "Tiger" }
]
}
},
{
"name": "not-found",
"statusCode": "404",
"body": {
"message": "No animals found"
}
},
{
"name": "server-error",
"statusCode": "500",
"body": {
"message": "Internal server error"
}
}
]
}
}
}
nameResponse must match one of the name values. Here the default is "success".
Call it
curl -i http://localhost:3001/data/animals
You should see:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"animals":[{"id":1,"name":"Lion"},{"id":2,"name":"Tiger"}]}
Point your app at http://localhost:3001. Same GET as production — this body is the happy path.
Flip to 404
Change only this line:
"nameResponse": "not-found"
Save. Watch reloads. Run the same curl again:
HTTP/1.1 404 Not Found
{"message":"No animals found"}
No new route. No frontend change. Same GET /data/animals.
Flip to 500
"nameResponse": "server-error"
Save and curl once more:
HTTP/1.1 500 Internal Server Error
{"message":"Internal server error"}
That is the whole feature: same URL, different backend behavior, one string in JSON.
nameResponse |
Status | Body |
|---|---|---|
success |
200 | list of animals |
not-found |
404 | error message |
server-error |
500 | error message |
Use the 404 for empty/not-found UI. Use the 500 for the generic failure banner. Switch back to success when you need the list again.
Same idea on POST
You can attach another responses array to POST on the same path. nameResponse is per method:
{
"data/animals": {
"GET": {
"nameResponse": "success",
"responses": [
{
"name": "success",
"statusCode": "200",
"body": {
"animals": [
{ "id": 1, "name": "Lion" }
]
}
},
{
"name": "server-error",
"statusCode": "500",
"body": { "message": "Internal server error" }
}
]
},
"POST": {
"nameResponse": "created",
"responses": [
{
"name": "created",
"statusCode": "201",
"body": {
"id": 3,
"name": "Eagle",
"created": true
}
},
{
"name": "server-error",
"statusCode": "500",
"body": { "message": "Could not save animal" }
}
]
}
}
}
curl -i -X POST http://localhost:3001/data/animals \
-H "Content-Type: application/json" \
-d '{"name":"Eagle"}'
With "nameResponse": "created" you get 201. Set it to "server-error" and the same POST returns 500.
GET and POST do not share nameResponse. You can have a healthy list and a failing create at the same time.
What you just got
- Several scenarios on one endpoint, in a file the team can review
- 200 / 404 / 500 (and 201 on POST) without touching the client
- A switch that is one key:
nameResponse
Links
- npm: http-mock-json
- GitHub: alejandrorodrom/http-mock-json
- Docs: rodriguezrom.com/libraries/http-mock-json
If this helps, drop a ⭐ on the repo or comment which status you mock first.
Top comments (0)