DEV Community

Cover image for Switch Success and Error Without Touching Your Frontend
Alejandro Rodriguez
Alejandro Rodriguez

Posted on

Switch Success and Error Without Touching Your Frontend

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 curl and 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
Enter fullscreen mode Exit fullscreen mode

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"
          }
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

nameResponse must match one of the name values. Here the default is "success".

Call it

curl -i http://localhost:3001/data/animals
Enter fullscreen mode Exit fullscreen mode

You should see:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"animals":[{"id":1,"name":"Lion"},{"id":2,"name":"Tiger"}]}
Enter fullscreen mode Exit fullscreen mode

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

Save. Watch reloads. Run the same curl again:

HTTP/1.1 404 Not Found

{"message":"No animals found"}
Enter fullscreen mode Exit fullscreen mode

No new route. No frontend change. Same GET /data/animals.

Flip to 500

"nameResponse": "server-error"
Enter fullscreen mode Exit fullscreen mode

Save and curl once more:

HTTP/1.1 500 Internal Server Error

{"message":"Internal server error"}
Enter fullscreen mode Exit fullscreen mode

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" }
        }
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
curl -i -X POST http://localhost:3001/data/animals \
  -H "Content-Type: application/json" \
  -d '{"name":"Eagle"}'
Enter fullscreen mode Exit fullscreen mode

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

If this helps, drop a ⭐ on the repo or comment which status you mock first.

Top comments (0)