/ mock

Setting up a Mock API for your Front-End (React) Project

There are times when you're working on the frontend for a project and you need to setup a mock API as the backend has not been completed or is currently in progress.

At work I was recently required to build out the front-end of a project in React before the backend for the project had been built. I also strongly believe that all frontend projects in a work environment should have a working mock API that allow the app to run standalone and for any new developers to do three things:

  1. Run npm i
  2. Run npm start (or similar)
  3. Open up their browser and use ALL functionalities of the frontend app

I've had to work on projects that do not work locally by themselves and it can be quite annoying when trying to get the database into a certain state, and configuring other local APIs that need to be running in parallel, all just to get the simple frontend app working.

I'm going to cover how you can quickly and easily create your own little mock API that will allow your app to run without any other dependencies!

For this article, I'm assuming that you are using Create React App.

Setting up the Mock API

Installing connect-api-mocker

The npm library that I used to help me mock my API is called connect-api-mocker.

connect-api-mocker is a connect.js middleware that fakes REST API server with filesystem. It will be helpful when you try to test your application without the actual REST API server.

More can be read in this Medium article.

connect-api-mocker can be used with a bunch of Node libraries such as Connect, Express and BrowserSync. But we'll be using Express.

Install the library using:

npm i --save-dev express connect-api-mocker

Then create a mock-api.js file in the root directory and put the following inside it:

var express = require('express');
var apiMocker = require('connect-api-mocker');
 
var app = express();
 
app.use('/api', apiMocker('mock-api'));
 
app.listen(9000);

Creating your mocks

For the purpose of this article, we are going to have 2 different API endpoints that our React app will consume:

GET
/user/:userName

CASE 1:
userName = "harvey" => 
Status: 200
Response: 
{
    "id": 1,
    "userName": "harvey",
    "age": "24"
}

CASE 2:
userName = "unauthorised" => 
Status: 403
Response : { }

CASE 3:
userName = * ({USERNAME}) => 
Status: 200
Response :
{
    "id": 0,
    "userName": {USERNAME},
    "age": "20"
}
POST
/user

CASE 4:
Body:
{
    "id": 3,
    "userName": "goodBoy",
    "age": 35
}
=>
Status: 201
Response: 
{
    "id": 2
}

CASE 5:
Body:
{
    "id": 1,
    "userName": "harvey",
    "age": 20
}
=>
Status: 209
Response: 
{
    "errorMessage": "UserId already exists"
}

connect-api-mocker allows you to create mocks using your filesystem. This means that instead of having to create an API that is similar to what is being used in your other environments, you can structure your mock API using directories and files. I was a bit skeptical of creating my mock API like this, but found it to be very easy to create and maintain.

In the root directory, create a folder called mock-api. Now we will mock the three different reponses our first GET endpoint returns.

Case 1

In mock-api create a user directory and within it, create another directory called harvey. In the harvey directory, create GET.json and place within it:

{
    "id": 1,
    "userName": "harvey",
    "age": "24"
}

You should now have a folder structure that looks like this:

/mock-api
    /user
        /harvey
            GET.json

Now, if you run mock-server.js and then in Postman, do a GET request on http://localhost:9000/user/harvey, you should receive the JSON we placed in the GET.json file! Hopefully this simple example shows how the folder structure maps to the API route.

Case 2

In /mock-api/user, create the directory unauthorised. In unauthorised, create a GET.js and place the following within it:

module.exports = (request, response) => response.status(403).send({ });

Directory should now look like:

/mock-api
    /user
        /harvey
            GET.json
        /unauthorised
            GET.js

This is a custom response and more can be read about them in the connect-api-mocker documentation..

Hit http://localhost:9000/user/harvey in Postman and you should see a 403 returned.

Case 3

This will be the catch-all case, so any request that you send other than harvey and unauthorised will return this. We will be utilising the wildcard feature connect-api-mocker ships with:

Create __userName__ under /user and place a GET.js within it. In GET.json:

module.exports = (request, response) => {
  response.json({
    id: 0,
    userName: request.params.userName,
    age: 20
  });
}

Now your structure should be:

/mock-api
    /user
        /harvey
            GET.json
        /unauthorised
            GET.json
        /__userName__
            GET.js

Open up Postman and send a request like: http://localhost:9000/user/testtest and you should recieve:

{
    "id": 0
    "userName": "testtest",
    "age": 20
}

Case 4 and 5

Our final two cases will be handled by a single file called POST.js. Create POST.js under /user and place within it:

module.exports = (request, response) => {
    const userId = request.body.id;
    if (userId === 1) {
        return response.status(409).send({});
    }
    
    return response.status(201).send({
        "id": request.body.id,
        "userName": request.body.userName,
        "age": request.body.age
    });
}

Your final mock-api directory structure should look like:

/mock-api
    /user
        /harvey
            GET.json
        /unauthorised
            GET.json
        /__userName__
            GET.js
        POST.js

In Postman, A POST to http://localhost:9000/user with a body that has id for 1 will return a 409 CONFLICT and a body with an id that is not 1 will now return 201 CREATED with the created body data.

Now we have successfully created our Mock API! Now we will configure our React app to consume it correctly.

Configure the proxy

Since the mock API is running in a different domain, you might run into CORS issues. To fix this, add:

"proxy": 9000

into your package.json.

Read more about CRA proxy here

Configure API endpoints

Throughout your React app, you will need to consume the mock API a specific way. For example, if we were to consume CASE 1, we would need to do something like:

    const res = await fetch('/api/user/harvey');

Replace all your endpoints through the app in a similar way.

Running the Mock Server

You will usually want to run the mock server the same time as you spin up your React application. To do this, we will be making some changes to the package.json scripts.

To run both at once, I used npm-run-all. This library allows you to run multiple npm scripts in parallel. Install using:

npm i --save-dev npm-run-all

Now in your package.json, under "scripts", add the two entries:

"mock-api": "node ./mock-api.js",
"dev": "run-p start mock-api"

Now run both using npm run dev.

Your React app will now consume the mock API routes! Enjoy!