Creating my first RESTful API with Node.js (part 1)

Since I started writing this article I have made huge progress on both the server and the client. Hopefully I am able to recall the progress accurately.

REST APIs have been quite a popular occurrence in the past few years and I have never actually dove into them. I kind of knew what they and were and did but not quite good enough. It was time for a change. In the past 3 months I have taken a nose dive in Node.js, AngularJS, VPSs, ssh and all that comes with it. I have also applied (and am still applying) Vertx in my bachelor project and even though the deployment part confused me, Vert.x is pretty awesome and so is Tim Fox (which, by the way, responds to your Vert.x questions blazingly fast!) for creating it.

From the above paragraph you might have spotted a common denominator: servers. Yes, until recently my focus has been more towards client-side areas (web apps, native apps, usability and such) but hardly at the back-end portion (aside from PHP frameworks and SQL databases that is). Due to me having to create a certain server for the bachelor project I figured it would be a good time to switch my focus entirely.

This brings me to my next point. I came onto a new idea which heavily, if not totally, relies on an easy and accessible API server. REST seemed to be the obvious choice and so I bombarded my browser with webpages on REST (APIs), Node.js (which I picked as back-end application), ExpressJS and Securing REST APIs.

I am hoping that people with more experience will correct me and people with less experience find this helpful.

The idea

The idea, of course, is to create a REST API that is both clear and secure. The first part should not be too difficult, while the second opposes more of a problem and for which I hope to receive tips. This article is limited to creating the API part without security. Later parts will focus on security and finishing touches.

What the product is I cannot yet reveal until it is at a later stage

REST

Me explaining REST would be a possibility, but there are already many other guides so I will post some of the better articles that I have read:

Node.js

The fact that you are here probably means you know what Node.js is. If not, the creators describe it as:

Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

- Creators of NodeJS

The reason of me wanting to use this is that I came across it more and more often and it seemed like a fun and easy way to get started with creating server-sided stuff.

Hapi

I have been searching for a nice framework for Node.js and tried several listed at NodeFramework. Unfortunately, none of them really made me enjoy the development process until I came across Hapi. It is very easy to get started and actually see results rather quickly. The coding style also attracted me and the repo is actively maintained. Some resources:

MongoDB

Until recently I have exclusively worked with SQL databases and languages other than JavaScipt. Having read quite a few articles that mentioned MongoDB it got me interested and as it happens it's perfectly suited for Node.js with Mongoose.

First few days

During the first few days after the idea I messed around a little: tried to create some dynamic forms in JavaScript, test some server frameworks for Node.js, looked into databases and brainstormed about the project. It gave me a general guideline of what I wanted to create and achieve with it, more on that once I am at a further stage.

Starting with Hapi, local data

One of the first things I did is play around with Hapi, create a simple server, look through the documentation, just trying stuff. I especially looked at the source code of the Postmile api example. During this entire phase I used local data to alter. If I can recall correctly I used an array of names with routes to return all names, name at a specific index, adding, altering or removing a name. At this moment I came across Joi, a validation framework by the developers of Hapi which offered seamless integration with Hapi. After getting more of a feeling with both Hapi and Joi I figured it was time to switch my focus to MongoDB.

Connecting to MongoDB

I wanted to move the names data, which I stored in local variables up until now, into a database. I remembered having read about Mongoose a while ago so I looked it up and it seemed like the best choice for my purposes. Hooking it up was extremely easy:

npm install mongoose --save  
var Mongoose = require('mongoose');

//load database
Mongoose.connect('mongodb://localhost/test');  
var db = Mongoose.connection;

db.on('error', console.error.bind(console, 'connection error'));  
db.once('open', function callback() {  
console.log("Connection succeeded here");  
});

Creating simple client to make testing easier

I am not a big fan of planning ahead really far and thorough, I rather plan a little and then implement that part while writing down new things. Considering I was already using JavaScript for my server I figured I could give Angular a try as well.

It's very easy to add functionality to Angular applications using plugins and I didn't quite like how you handle http calls in Angular so I searched for a plugin. Luckily there's one that's quite widely used: Restangular.

The first mistake

It was bound to happen: a mistake that required me to rewrite a somewhat large portion of my code. Everything worked great and expanding it was easy, but I forgot that it should work with other services as well. Shortly before realizing this I had a small demo during a meeting for my bachelor project. The client liked it and allowed us to integrate this in our project. One issue: in our project we use a SQL database and have our own users and groups. Storing users and groups in my API would cause the hassle of maintaining two databases but it also meant a possible privacy conflict. The latter was something I kept in my mind from the beginning: privacy sensitive data wasn't necessary for it to work, it just enhanced the experience. The former led to some issues, because I had to find a way to connect the users and groups to function with my system.

While I am still thinking about it I did remove all users and groups related code from my API, allowed the userIds to be something other than MongoDB's ObjectId. Unfortunately this also meant that clients should handle permissions for themselves.

Closing

Even though REST is deemed easy I still find it challenging to implement (properly). I still support the choices I made regarding which software to use (Node.js, MongoDB and Hapi) and enjoy working with it.

In the next post I hope to explain certain choices and/or solutions into more detail, because this post may still be somewhat vague.

comments powered by Disqus