What is RethinkDB?
• Open source database for building
realtime web applications
• NoSQL database that
stores schemaless JSON documents
• Distributed database that is easy to
scale
Slide 5
Slide 5 text
Built for Realtime Apps
• Subscribe to change notifications
from database queries
• No more polling — the database
pushes changes to your app
• Reduce the amount of plumbing
needed to stream live updates
Additional ReQL Features
• Geospatial indexing for location-
based queries
• Date and time functions for time
data
• Support for storing binary objects
• Execute http requests using r.http
Changefeeds
r.table("players")
.orderBy({index: r.desc("score")})
.limit(3).changes()
Track top three players by score
Chain the changes command
to an actual ReQL query:
Building Web Apps
Using RethinkDB with
Angular+Node.js
Slide 28
Slide 28 text
Demo: Realtime Chat
Slide 29
Slide 29 text
What we need
• Add http enpoints for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Slide 30
Slide 30 text
What we need
• Add http endpoints for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Slide 31
Slide 31 text
What we need
• Add http endpoints for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Slide 32
Slide 32 text
What we need
• Add http endpoints for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Slide 33
Slide 33 text
HTTP endpoints with Node.js
var express = require('express');
var app = express();
var server = require('http').Server(app);
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
// ...
});
server.listen(8000);
Create HTTP routes for messages
Slide 34
Slide 34 text
var express = require('express');
var app = express();
var server = require('http').Server(app);
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
// ...
});
server.listen(8000);
Declare POST endpoint
HTTP endpoints with Node.js
Slide 35
Slide 35 text
app
.post('/message', function (req, res) {
return r.table('messages').insert({
text: req.params.text,
email: req.params.email,
created: (new Date()).getTime()
}).run(r.conn);
})
.get('/message', function (req, res) {
// ...
})
Get `messages` table
HTTP endpoints with Node.js
Slide 36
Slide 36 text
app
.post('/message', function (req, res) {
return r.table('messages').insert({
text: req.params.text,
email: req.params.email,
created: (new Date()).getTime()
}).run(r.conn);
})
.get('/message', function (req, res) {
// ...
})
`insert` new document
HTTP endpoints with Node.js
Slide 37
Slide 37 text
app
.post('/message', function (req, res) {
return r.table('messages').insert({
text: req.params.text,
email: req.params.email,
created: (new Date()).getTime()
}).run(r.conn);
})
.get('/message', function (req, res) {
// ...
})
Run the query
HTTP endpoints with Node.js
Slide 38
Slide 38 text
var express = require('express');
var app = express();
var server = require('http').Server(app);
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
// ...
});
server.listen(8000);
Declare GET route
HTTP endpoints with Node.js
Slide 39
Slide 39 text
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
return r.table('messages')
.orderBy({ index: 'created'})
.coerceTo('array')
.run(r.conn)
.then(function (messages) {
res.json(messages);
});
})
Get `messages` table
HTTP endpoints with Node.js
Slide 40
Slide 40 text
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
return r.table('messages')
.orderBy({ index: 'created'})
.coerceTo('array')
.run(r.conn)
.then(function (messages) {
res.json(messages);
});
})
Order by time created
HTTP endpoints with Node.js
Slide 41
Slide 41 text
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
return r.table('messages')
.orderBy({ index: 'created'})
.coerceTo('array')
.run(r.conn)
.then(function (messages) {
res.json(messages);
});
})
Run the query
HTTP endpoints with Node.js
Slide 42
Slide 42 text
app
.post('/message', function (req, res) {
// ...
})
.get('/message', function (req, res) {
return r.table('messages')
.orderBy({ index: 'created'})
.coerceTo('array')
.run(r.conn)
.then(function (messages) {
res.json(messages);
});
})
Return the results of the query
HTTP endpoints with Node.js
Slide 43
Slide 43 text
What we need
• Add http endpoints for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Slide 44
Slide 44 text
Message Factory (Client)
angular.module('rethinkDBWorkshop.services', [])
.factory('MessageFactory', MessageFactory);
MessageFactory.$inject = ['$http', '$rootScope'];
function MessageFactory ($http, $rootScope) {
var messageCollection = [];
var factory = {
insertMessage: insertMessage,
getMessageCollection: getMessageCollection,
};
factory.getMessageCollection();
return factory;
}
Creating factory for messages
Message Factory (Client)
angular.module('rethinkDBWorkshop.services', [])
.factory('MessageFactory', MessageFactory);
MessageFactory.$inject = ['$http', '$rootScope'];
function MessageFactory ($http, $rootScope) {
var messageCollection = [];
var factory = {
insertMessage: insertMessage,
getMessageCollection: getMessageCollection,
};
factory.getMessageCollection();
return factory;
}
Add method for adding messages
Slide 49
Slide 49 text
Message Factory (Client)
angular.module('rethinkDBWorkshop.services', [])
.factory('MessageFactory', MessageFactory);
MessageFactory.$inject = ['$http', '$rootScope'];
function MessageFactory ($http, $rootScope) {
var messageCollection = [];
var factory = {
insertMessage: insertMessage,
getMessageCollection: getMessageCollection,
};
factory.getMessageCollection();
return factory;
}
Add method for getting messages
Slide 50
Slide 50 text
Message Factory (Client)
var factory = {
insertMessage: function (text) {
return $http.post('/message', {
text: text,
email: config.email
});
},
getMessageCollection: function () {}
};
Send POST http request
Slide 51
Slide 51 text
Message Factory (Client)
var factory = {
insertMessage: function (text) {
return $http.post('/message', {
text: text,
email: config.email
});
},
getMessageCollection: function () {}
};
Send object to be inserted
Slide 52
Slide 52 text
Message Factory (Client)
var factory = {
insertMessage: function (text) { },
getMessageCollection: function () {
return $http.get('/message')
.then(function (res) {
messageCollection.splice(0, Infinity);
res.data.forEach(function (row) {
messageCollection.push(row);
});
return messageCollection;
});
}
};
GET messages from server
Slide 53
Slide 53 text
Message Factory (Client)
var factory = {
insertMessage: function (text) { },
getMessageCollection: function () {
return $http.get('/message')
.then(function (res) {
messageCollection.splice(0, Infinity);
res.data.forEach(function (row) {
messageCollection.push(row);
});
return messageCollection;
});
}
};
Remove all messages from array
Slide 54
Slide 54 text
Message Factory (Client)
var factory = {
insertMessage: function (text) { },
getMessageCollection: function () {
return $http.get('/message')
.then(function (res) {
messageCollection.splice(0, Infinity);
res.data.forEach(function (row) {
messageCollection.push(row);
});
return messageCollection;
});
}
};
Add all messages to array
Slide 55
Slide 55 text
What we need
• Add http endpoint for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Node.js Server
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Listen for new socket connections
Slide 59
Slide 59 text
Node.js Server
Create a new database connection
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Slide 60
Slide 60 text
Node.js Server
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Get `messages` table
Slide 61
Slide 61 text
Node.js Server
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Listen to changes in our messages
Slide 62
Slide 62 text
Node.js Server
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Run the query
Slide 63
Slide 63 text
Node.js Server
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Pass a callback to our cursor
Slide 64
Slide 64 text
Node.js Server
var io = require('socket.io')(server);
io.on('connection', function (socket) {
r.connect(config.get('rethinkdb'))
.then(function (conn) {
r.table('messages')
.changes().run(conn)
.then(function (cursor) {
cursor.each(function (err, row) {
socket.emit('message', row.new_val);
});
});
});
});
Send new message to the client
Slide 65
Slide 65 text
What we need
• Add http endpoints for getting and
adding messages
• Create an Angular factory for
messages
• Setup changefeed in Node.js app
• Add realtime listener in factory
Slide 66
Slide 66 text
Message Factory with Changefeeds
function MessageFactory ($http, $rootScope) {
var socket = io.connect('http://' + config.url);
var messageCollection = [];
socket.on('message', function (message) {
$rootScope.$apply(function () {
messageCollection.push(message);
});
});
var factory = { ... };
return factory;
}
Add new message handler
Slide 67
Slide 67 text
Message Factory with Changefeeds
function MessageFactory ($http, $rootScope) {
var socket = io.connect('http://' + config.url);
var messageCollection = [];
socket.on('message', function (message) {
$rootScope.$apply(function () {
messageCollection.push(message);
});
});
var factory = { ... };
return factory;
}
Connection to Socket.io server
Slide 68
Slide 68 text
Message Factory with Changefeeds
function MessageFactory ($http, $rootScope) {
var socket = io.connect('http://' + config.url);
var messageCollection = [];
socket.on('message', function (message) {
$rootScope.$apply(function () {
messageCollection.push(message);
});
});
var factory = { ... };
return factory;
}
Listen to new messages on socket
Slide 69
Slide 69 text
Message Factory with Changefeeds
function MessageFactory ($http, $rootScope) {
var socket = io.connect('http://' + config.url);
var messageCollection = [];
socket.on('message', function (message) {
$rootScope.$apply(function () {
messageCollection.push(message);
});
});
var factory = { ... };
return factory;
}
Perform proper scope life cycle
Slide 70
Slide 70 text
Message Factory with Changefeeds
function MessageFactory ($http, $rootScope) {
var socket = io.connect('http://' + config.url);
var messageCollection = [];
socket.on('message', function (message) {
$rootScope.$apply(function () {
messageCollection.push(message);
});
});
var factory = { ... };
return factory;
}
Push message into collection