TQ
dev.com

Blog about software development

Subscribe

Simple REST API in Node.js

17 Jan 2017 - by 'Maurits van der Schee'

I have written a simple REST API in Node.js. It includes routing a JSON REST request, converting it into SQL, executing it and giving a meaningful response. I tried to write the application as short as possible and came up with these 110 lines of code:

var http = require("http");
var mysql = require("mysql");

// connect to the mysql database

var pool = mysql.createPool({
  connectionLimit: 100, //important
  host: 'localhost',
  user: 'my_username',
  password: 'my_password',
  database: 'my_database',
  charset: 'utf8',
  debug: false
});

// ensure request has database connection

var withDb = function (handler) {
  return function (req, resp) {
    pool.getConnection(function (err, connection) {
      if (err) {
        resp.writeHead(404)
        resp.end(err);
        return;
      }
      req.db = connection;
      handler(req, resp);
    });
  }
};

// ensure request has (post) body

var withBody = function (handler) {
  return function (req, resp) {
    var input = "";
    req.on("data", function (chunk) {
      input += chunk;
    });
    req.on("end", function () {
      req.body = input;
      handler(req, resp);
    });
  }
};

// main web handler

var server = http.createServer(withDb(withBody(function (req, resp) {

  // get the HTTP method, path and body of the request
  var method = req.method;
  var request = req.url.replace(/^[\/]+|[\/]+$/g, '').split('/');
  try {
    var input = JSON.parse(req.body);
  } catch (e) {
    var input = {};
  }

  // retrieve the table and key from the path
  var table = req.db.escapeId(request.shift());
  var key = req.db.escape(request.shift());

  // create SQL based on HTTP method
  var sql = '';
  switch (req.method) {
    case 'GET':
      sql = "select * from " + table + (key ? " where id=" + key : '');
      break;
    case 'PUT':
      sql = "update " + table + " set ? where id=" + key;
      break;
    case 'POST':
      sql = "insert into " + table + " set ?";
      break;
    case 'DELETE':
      sql = "delete " + table + " where id=" + key;
      break;
  }

  // execute SQL statement
  req.db.query(sql, input, function (err, result) {

    // stop using mysql connection
    req.db.release();

    // return if SQL statement failed
    if (err) {
      resp.writeHead(404)
      resp.end(err);
      return;
    }

    // print results, insert id or affected row count
    resp.writeHead(200, {
      "Content-Type": "application/json"
    })
    if (req.method == 'GET') {
      resp.end(JSON.stringify(result));
    } else if (method == 'POST') {
      resp.end(JSON.stringify(result.insertId));
    } else {
      resp.end(JSON.stringify(result.affectedRows));
    }

  });

})));

server.listen(8000);

The code is available on Github and is written to show you how simple it is to make a fully operational REST API in JavaScript.

Multi-threading

Node.js applications are single threaded by default. With the "cluster" package, as shown in the code below (source), you can make Node.js use multiple cores.

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    http.createServer(function(req, res) {
        res.writeHead(200);
        res.end('process ' + process.pid + ' says hello!');
    }).listen(8000);
}

Note that using "cluster" has quite some overhead, so only do this when you have lots of cores and some cores of your machine are actually idle under full load.

Running

To run the application you need to install Node.js (node) and Node Package Manager (npm). On Ubuntu Linux you can do this by running:

sudo apt-get install nodejs nodejs-legacy npm

To install the application's dependencies type:

npm install mysql

To run the application type:

node app.js

The URL you need to open in your browser is:

http://localhost:8000/{table-name}/{record-id}

NB: Don’t forget to adjust the database parameters in the above script!

REST API in a single JavaScript file

Although the above code is not perfect it actually does do 3 important things:

One could thus say that the REST API is fully functional. You may run into missing features of the code, such as:

Don’t worry, all these features are available in php-crud-api, which you can get from Github. On the other hand, now that you have the essence of the application, you may also write your own!