Tuesday, August 02

Easy API mocking with Node-RED


Introduction

Imagine the following:

You are working on a brand new social app and you have to put in place a screen displaying all the friends you have. In most of the cases you are going to rely on a web service to load that list for you. You could use something like the following endpoint:

baseURL/socialapp/user-id/friends

This endpoint would return something like:

{
    "data": [{
        "name": "Danielle Myers",
        "id": "284739"
    }, {
        "name": "Terry Williams",
        "id": "294873"
    }, {
        "name": "Jo Kim",
        "id": "3902733"
    }]
}

This is an ideal scenario where all the endpoints you need are already implemented and available for you. But most of the times, this will not be the case.

You could already start implementing the code handling the UI of your app but without any data it can be troublesome.

One solution is to hardcode the data and see how your UI looks like with these fake (=mock) data.

Yet, there are several drawbacks with this approach:

If you could simulate the behavior of that non existing endpoint it would solve all the problems.

Node-RED solves these issues by letting you create any endpoints and responses you want. It can run on your own computer or on a separate machine (you only need to change the base url of your request). Plus, it comes with a simple and visual interface, which can speed up your development.

Node-RED

Node-RED is a visual tool developed by IBM.

Go to the official website and follow the instructions to install it. Once it is done, open it:

http://127.0.0.1:1880/

You will see the following screen:

node-red default screen

Node-red has a straightforward user interface. You only need to drag & drop the nodes you need. Once connected to each other, these nodes create a flow.

This flow will match an endpoint and send the desired mocks for your. You can also organize your flows into different tabs.

Examples

Let’s get back to our endpoint:

/socialapp/user-id/friends

To mock it, you will have to drag and drop the following nodes:

1) http input node

Used to match an endpoint. Double click on it to configure it. Choose GET for the http method and enter the following url:

/socialapp/[0-9]*/friends

input node

This tells Node-RED to call this node every time your app will call the GET friends' list endpoint. As you can see, you can also use regular expressions. So calling /socialapp/123/friends or calling /socialapp/999/friends will produce the same effect.

2) file storage node

The file node reads the content of a specified file and sends it as the body of the message. So this node provides the content of the response.

file storage node

In this case, we will want to receive a JSON response, the content of the file will be something like:

{
    "data": [{
        "name": "Danielle Myers",
        "id": "284739"
    }, {
        "name": "Terry Williams",
        "id": "294873"
    }, {
        "name": "Jo Kim",
        "id": "3902733"
    }]
}

3) function node

A function node is a node where you can write Javascript code. Inside it, you can for instance change the status code or the headers of your desired mock response.

function node

By the way, you can access the response’s body with the msg.payload variable (remember, this is where the file node writes its output).

4) http response node

The last node to include is the http response node. This node sends back the response to the request received from our first http input node. By default, the status code is 200 (so actually our function node here is useless but we keep it as an example).

Don’t forget to connect all the nodes to create your flow. Once everything is done. Click on deploy.

completed flow

Integration with iOS

Congratulation, you have just created your first endpoint. But it needs now to work with your app.

As we saw, Node-RED can be accessed at:

http://127.0.0.1:1880/

This address needs to replace the base url that you usually use for your endpoints:

http://127.0.0.1:1880/socialapp/user-id/friends

Keep in mind that you might encounter issues if you have enabled App Transport Security in your app. ATS only allows https connections while the localhost uses http. Apple allows you to whitelist domains name but not IP addresses.

To fix this you can open /etc/hosts and add the following line (if it’s not already there).

127.0.0.1       localhost

Once it is done you can add localhost to your ATS whitelist. Here is one of my plist as an example:

plist example

You have now an app that can use Node-RED locally. You can switch between a mock/production environment simply by changing the base url of your requests.

Conclusion and final remarks

We saw how Node-RED can be used to mock any API we need in our projects. However, keep in mind that Node-RED can come in handy for something else too, UI testing.

Indeed, when doing UI testing, it is important to keep the tests isolated and consistent. We do not want our tests to interfere with real data nor receive different data every time we run them. I found Node-RED to combine perfectly with the UI Testing framework from Xcode.

We covered a simple endpoint, Node-RED can do much more than that.

You can add delays in your responses, read the headers of your requests, send appropriate responses using switch and if/else conditions, etc.

If you want to go further, do not hesitate to play around with the different nodes and read the documentation on the official website.

Happy coding.