A blog by Juri Urbainczyk | Juri on Google+ | Juri on Twitter | Juri on Xing

Wednesday, April 8, 2015

Implementing a REST API with node.js

Every so often there is the necessity to implement some mock-up web services or maybe even a prototype which shall offer its functionality via web services. This happened to me once again in March 2015 when preparing the API for a hackathon. To be precise, there already was an API, but it did not really fit to the requirements of the hackathon’s sponsor. Therefore, we decided to implement a second API (as a mock API) on top of the existing one. Our, second, API should add additional functionality to the existing services.
It was quite clear that the API should be REST with JSON as transport protocol. Unfortunately, we only had less than 4 weeks to design, implement and test the mock API. Thus, only a very lightweight technology could make this possible, like node.js.
Being JavaScript on the server, node.js is indeed a very lightweight technology. In its most basic configuration it will require you to write only one JavaScript file, which is then read and executed by node. Furthermore, it come with a module concept which lets you include already existing modules into your code with the “require” statement. Node also brings a packet manager (named “npm”) which lets you easily install all those modules to your project’s file system. In our mock API we used the following imports:
var http = require('http');
var express = require('express');
var url = require( "url" );
var path = require("path");
var fs = require("fs");
var queryString = require( "querystring" );

For our purposes, the “express” module is very important: it enables us to write REST services like in the following example. This short piece of code implements a web service, using the HTTP “GET” method, which echoes all input back to the response.

var api = express();

api.get('/echo', function(req,res) {

       var myobj = "";
        // parses the request url
        var theUrl = url.parse( req.url );
        //check if there is a query       
        if ((theUrl.query != null) && (theUrl.query != "")) {

             // gets the query part of the URL and parses it creating an object
             var queryObj = queryString.parse( theUrl.query );
             // queryObj contains the data of the query as an object
             // and jsonData is a property of it
             myobj = JSON.parse( queryObj.jsonData );                   

       res.json( myobj );

As this examples shows, it’s really quite simple. For the response, you have to create a JavaScript object (which also might be a quite big one with arrays included and so on…) and transform it to JSON with “res.json”. This data is then returned to the client. There is a catch, though: with a HTTP “GET” method the input parameters will be encoded in the URL and therefore there is an upper limit of data which can be input to the service (around 8 kB, depending on the browser and other factors).  So, in order to potentially input more data into the web service, a “POST” method should be used, like in the next example. This one also shows how to extract parameters from the request header and do some basic authentication. Anyway, please bear in mind, it's still only a prototype source code (e.g. there should be another return code than 400 if an error occurred).'/api/booking', function (request, response) {

     //Read header & body
     var jsonData = request.body.requestPayload;

     var requestID = request.header('requestId');
     var userName = request.header('userName');
     var userPassword = request.header('password')
     var timeStamp = request.header('timeStamp');

     if (!checkAuthWithResponse(userName, userPassword, response)) return;

     resultAsString = '';

     var err = oVali.runHeaderValidation(request);
     if (err.length > 0) {
          // some logging and error handling here
     } else {

          // some business logic here


     Response.send( resultAsString, 400);

Our mock API was intended to implement additional business logic on top of the existing API. The client would then call the mock API’s services to execute this business logic. Because the logic would only be depending on the values of the input parameters of the services there was no need for additional data storage or caching. Nevertheless, it would be quite easy as well to integrate a NoSQL database into node.js, for example.
Our mock API based on node.js was implemented just in time for the Hackathon and it was used there with very good results. We experienced no outages and had no problems with the performance as well.

As a summary, what are the advantages of using node.js for REST API development? We can name the following:

  1. As a developer, you are up and running very quickly. Install node, download some modules, write ONE file, and you are done.
  2. You don’t need to learn a lot of tools and IDEs (low overhead).
  3. The feedback cycles are very short, enabling you to develop with high speed.
  4. Integration with file system and databases is easy.
  5. Many standard problems can be used out-of-the-box with only a few lines of code.
  6. There is a big community, helping you out if you run into problems. Online documentation and FAQ is huge.
  7. It’s very easy to transport node projects. Just zip and unzip the files and you are done.
  8. There are a lot of possibilities to deploy and run node projects on the web. Pricing starts very low as well.

The bottom line is: node.js is a perfect choice for implementing prototype REST services. In how far this could be extended to full blown operational services – that’s another matter.

No comments:

Post a Comment