IN THIS ARTICLE
Recently, I have become interested in using RethinkDB as my preferred document based database. Although RethinkDB and MongoDB have their own similarities and differences, it’s RethinkDB’s real-time web feature and their query language that has impressed me the most. If you have been following my previous posts, you might have seen a pattern emerging that I tend to explain with real life examples. This is no different. This article will leverage RethinkDB’s realtime API to build library management software where a reader can see in real-time if a book is ‘available’ or ‘booked’.
Our primary focus in this tutorial is to observe changes in the status of a book on a server and then publish it to client. I have ignored the client side frameworks (like EmberJS, ReactJS AngularJS etc) or middleware (like Rails, ExpressJS etc) to explain the concept in a simple and clear way. You can of course choose whatever framework you like and these concepts will work just the same way.
RethinkDB Setup
You need to install RethinkDB on your system. You can install it using the RethinkDB official instructions.
To test if it’s installed, run ‘rethinkdb
’ from your terminal. In a browser, open localhost:8080
. RethinkDB admin should open up.
Server Side setup for Realtime Updates
In the RethinkDB admin panel, go to Tables. Inside the database ‘test’, add a table ‘books’.
Once the table ‘books’ is created, go to Data Explorer and run this query to create a book with name ‘Harry Potter’ and availability status as ‘Available’:
r.table('books').insert({name: "Harry Potter Series",
author: "J.K.Rowling", availability_status: “Available”})
Now install the rethinkdb and pubnub npm modules in your project folder:
npm install rethinkdb —save
npm install pubnub —save
The server side script looks like this:
var r = require('rethinkdb'); // Initialise rethinkdb instance var pubnub = require("pubnub")({ // Initialise pubnub instance subscribe_key: 'demo', // always required publish_key: 'demo' // only required if publishing }); // Establish a connection var connection = null; r.connect( {host: 'localhost', port: 28015}, function(err, conn) { if (err) throw err; connection = conn; // Get a book r.table('books').filter(r.row('name').eq("Harry Potter Series")) // Get a book with name 'Harry Potter' .changes() // Look for any changes happening to this record and keeps returning it .run(connection, function(err, cursor) { // run the above query on this connection if (err) throw err; cursor.each(function(err, result) { // If there is no error, it returns a cursor, which is collection of JSON objects if (err) throw err; pubnub.publish({ //publishing the updated Book's status through PubNub, in 'rethinkdb-pubnub' channel channel: "rethinkdb-pubnub", message: {"status" : result.new_val.availability_status}, //this is the message payload we are sending // result contains a new value and the old value of this record. This is due to .changes() method. callback: function(m){console.log(m)} }); console.log({"status" : result.new_val.availability_status}); }); }); }) // r.table('books').insert({name: "Harry Potter Series", author: "J.K.Rowling", availability_status: "Available"}) // r.table('books').filter(r.row("name").eq("Harry Potter Series")).update({availability_status: "Booked"})
Client Side Setup for Realtime Book Checkout
On client side, we have a basic HTML5 boilerplate with PubNub and jQuery loaded from a CDN.
The important part is initializing a PubNub instance and subscribing using the right sub-key and channel name.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>RethinkDB PubNub</title> <script src="index.js" charset="utf-8"></script> <script src="https://cdn.pubnub.com/pubnub-3.7.13.min.js"></script> <script src="jquery.js" charset="utf-8"></script> <style> #book{ margin: auto; display: block; text-align: center; } .available{ font-size: 50px; } /* #number{ font-size: 50px; color: #006600; } */ </style> </head> <body> <h1>Book Availablity</h1> <div id="book"> <span class="available">Harry Potter Series - <span id="availability_status"></span></span> </div> </body> <script type="text/javascript"> $(document).ready(function() { var pubnub = PUBNUB({ subscribe_key : 'demo' }); pubnub.subscribe({ channel : "rethinkdb-pubnub", // Subscribing to PubNub's channel message : function(message){ console.log(message); $("#availability_status")[0].innerHTML = message.status; // Embeding status inside the message that's coming through channel and putting it in HTML } }) }); </script> </html>
I didn’t spent time on writing query to find the book and embedding it in HTML etc as it could have complicated the example and shifted us from what we want to focus on, which is to get observe for changes in DB in real-time and then stream it.
To check if everything is working,
- open the index.html in browser
- run rethinkdb server
- run the script using node
index.js
. - Change the status of the book from Data Explorer using this command:
r.table('books').filter(r.row("name").eq("Harry Potter Series")).
update({availability_status: “Booked"}) - Change it to “Booked” or “Available” accordingly and you shall see the corresponding status in the browser.
Front End Design for Library Checkout Using RethinkDB
You can find the source code here.
Endless Realtime Possibilities with RethinkDB
RethinkDB’s real-time feature opens window to whole new possibilities. For example, in airports, you could see the status of flights in real-time. If a flight is getting delayed, you would normally update that from an admin dashboard and it would show up on all the screens instantly. Building realtime apps with RethinkDB is easy, including multiplayer games, marketplaces, streaming analytics and connected mobile devices. Whenever you get a chance to work on some idea which needs to interact with database and get the changes in real-time, PubNub and RethinkDB are a perfect combo.