Crud WebService for your json data in Node.JS and RethinkDB

nodejs

I started the habit of looking up what’s trending in GitHub every morning before start to work and it’s shown me very good benefits. I can see what people are using and interested in out there. I usually tweet the projects that really seems interesting and worth following, so if you want to know what I have found so far, particularly the ones related to Front-End development, find me on twitter.

One project that caught my eyes recently is RethinkDB, a NoSQL database that stores JSON documents and as they say on their website it has an “intuitive query language, automatically parallelized queries and simple administration“. I indeed like how easy it is to query data and how it handles JSON docs.

I created a simple REST web service using Node.JS and Express to persist schema-free JSON data in RethinkDB so that I can have a taste of how easily I can integrate this database with javascript. I put this web service up in GitHub, so feel free to clone and play around with it. Below I explain a how this web service (crud_ws) was built.

The crud_ws consists of basically 3 main files
- package.json – Define the dependencies of the project
- server.js – The controller of the webservice
- modules/crud.js – The logic to persist the data on RethinkDB

package.json
Here we are defining our dependency on express framework.

{
    "name": "crud_ws",
    "description": "CRUD",
    "version": "0.0.1",
    "private": false,
    "dependencies": {
        "express": "3.x"
    }
}

server.js
Notice here we define the routes and the respective http methods. For each route we say what method to execute.

var express = require('express'),
    module = require('./modules/crud'),
    app = express();

app.use(express.bodyParser());
app.get('/cruds', module.findAll);
app.get('/cruds/:id', module.findById);
app.post('/cruds', module.create);
app.delete('/cruds/:id', module.delete);
app.put('/cruds/:id', module.update);

app.listen(3000);
console.log('Listening on port 3000...');

modules/crud.js
Here we open the connection with the database and define all the methods that we call from server.js. findAll(), findById(), create(), update() and delete().

(function() {
  var r = require('rethinkdb'),
      connection;

  r.connect( {host: 'localhost', port: 28015}, function(err, conn) {
    if (err) throw err;
    connection = conn;
    r.db('test').tableCreate('cruds').run(conn, function(err, res) {
      if(err && err.name === "RqlRuntimeError") console.log("Table already exist. Skipping creation.");
      else {
        console.log(res);
        throw err;
      }
    });
  });

  exports.findAll = function(req, res) {
    r.table('cruds').run(connection, function(err, cursor) {
        if (err) throw err;
        cursor.toArray(function(err, result) {
            if (err) throw err;
            res.send(JSON.stringify(result, null, 2));
        });
    });
  };

  exports.findById = function(req, res) {
    var id = req.params.id;
    r.table('cruds').get(id).
      run(connection, function(err, result) {
          if (err) throw err;
          res.send(JSON.stringify(result, null, 2));
      });
  };

  exports.create = function(req, res) {
    var presentation = req.body;
    console.log("cruds ", JSON.stringify(req.body));
    var presentation = req.body;
    console.log(JSON.stringify(req.body));
    r.table('cruds').insert(presentation).
      run(connection, function(err, result) {
        if (err) throw err;
        res.send(JSON.stringify({status: 'ok', location: '/cruds/'+result.generated_keys[0]}));
      });
  };

  exports.update = function(req, res) {
    var presentation = req.body,
        id = req.params.id;
    r.table('cruds').get(id).update(presentation).
      run(connection, function(err, result) {
        if (err) throw err;
        res.send(JSON.stringify({status: 'ok'}));
      });    
  };

  exports.delete = function(req, res) {
    var id = req.params.id;
    r.table('cruds').get(id).delete().
      run(connection, function(err, result) {
          if (err) throw err;
          res.send(JSON.stringify({status: 'ok'}));
      });
  };
})();

To make all this work you need to:

- Start RethinkDB service

$ rethinkdb

- Install dependencies

$ npm install

- Start crud_ws service

$ node server.js

- Done! Test away!

#Creating
$ curl -X POST -H "Content-Type: application/json" -d '{"title":"Hey, I'm using crud_ws", "slides": [{"1":"test"}, {"2": "Another test"}]}' http://localhost:3000/cruds

#Retrieving
$ curl -i -H "Accept: application/json" http://localhost:3000/cruds

#Updating
$ curl X PUT -i -H "Accept: application/json" -d 'title'='This is the updated title' http://localhost:3000/cruds/23cd6e44-d2b4-47d0-ba87-b788c496c82c

#Deleting
$ curl -X DELETE -i -H "Accept: application/json" http://localhost:3000/cruds/446a7bc3-d54c-4f1b-812f-b8daa9bc2016

Javascript ES6: Learn important features in a few minutes



Learn even more with my other posts:
Closures: Probably the Simplest Way To Learn It
HTML5 pushState and Single-Page apps
Most Common Technical Interview Question for FrontEnd Developers

If you enjoyed this article, get free email updates

  • black boulez

    instead of throwing errors you might or might not be able to catch in a async loop, pass the error to the third argument of your controller function , which is called next : next(err);

  • roshiro

    Hey, Patrick.
    Thanks for you comment.

    I haven’t seen much of reQL and I have no experience with mongoose. By curiosity I took a look into mongoose docs and it seems to be very tied up to your models and is schema-based, different from rethinkdb. RethinkDB API does not involve validations and is schema-free.