During server software development (i.e. node) I always strive to work offline, in that my development workflow doesn't depend on any online services.

However, sometimes that's not possible as there's some 3rd party API dependancy - as there was in my latest client work. The problem I found, was that the latency between my location and the 3rd party API was so high, that it was impacting on the workflow cycle of: debug, change, test, repeat. The load time was taking anywhere from 15-30 seconds each time.

So this was my quick work around to easily mock out the API so my development process could be faster.

SPONSORBuddy: The DevOps Automation Platform

Get the most powerful and easy-to-configure continuous integration and delivery platform.

The aims

The aim was to, without much work at all, replicate specific API calls without modifying my application code. i.e. I could switch my mock API on and off as I needed.

It was also important that the time required to put a mock API in place, did not outweigh the time lost on the latency. Specifically, if the custom mock API turned into days of work, it would have been a total waste of time.

The simple solution

This code uses Express 4. It's entirely possible that there was a library that already existed, but the small amount of code that I had to write wins over finding, researching, checking and learning a new library.

Capturing mock data

First I had to run my way through each API call and save the raw output as a .json file in a local directory (not tracked in git) called mock-data.

Since all my internal API calls used a config value as the root of the API URL, it meant I could change my local config to point to my local mock API instead of the staging or production endpoint:

var config = require('./config');
var root = config.api;

function getOrder(id) {
  return request({ // a promise
    url: root + '/order',
    type: 'json',
    body {
      id: id
    }
  });
}

I would change my config.api value to point to `http://localhost/mock-api' and the server I was developing would actually reply to the API requests using the code in the next section.

Mock API Code

The following code would be in (something like) routes/mock-api.js:

var express = require('express');
var fs = require('fs');
var router = express.Router();
// directory path to the mock json files
var mockPath = __dirname + '/mock-data/';

var design = {
  'POST /order': 'getOrder',
  'POST /order/tickets': 'addTickets',
  'DELETE /order/tickets': 'removeTicket',
}

module.exports = router;

Object.keys(design).forEach(function (req) {
  var method = req.split(' ').shift();
  var path = req.split(' ').pop();
  var mock = '{}';
  try {
    mock = require(mockPath + design[req]);
  } catch (e) {}

  router.route(path)[method.toLowerCase()](function (req, res) {
    res.send(mock);
  });
});

In my main routes.js file I can then conditionally load up my mock router:

// snip...
if (config.mock) {
  app.use('/mock-api', require('./routes/mock-api'));
}

Now requests to my server (the same server I'm doing my main development against), can respond to API requests with pre-baked data. Now my damn latency is a thing of the past!

Taking it further

I struggle to look at the above code without seeing ways to improve it - but as I pointed out in the aims: keep it simple, and keep the solution quick.

Here's a few ideas that spring to mind that might make the code more useful in different situations:

  • Respond with different file types (rather than only .json)
  • Respond with inline JSON data (that would be defined in the design)
  • Support variables in the URL to pick different static responses (like GET /order/:id)

I have done some similar work in my static server which also has limited support for interpolation in the response.

For now though, this simple version suits my requirements!