SlideShare a Scribd company logo
1 of 51
Download to read offline
0 to App faster with NodeJS and Ruby
Rebecca Mills @RebccaMills
Patrick McFadin @PatrickMcFadin
The situation
• REST interface to Cassandra data
• Support CRUD operations
• It’s Friday and…
2
Umm yeah, and I’m going to
need that by Monday morning.
Choose your language
• Support for all Cassandra features
• Easy to work with
• Performant
3
Fast prototype
4
5
Need to get this done now
6
DataStax NodeJS driver
• Works with current OSS Cassandra
• Apache Licensed
7
https://github.com/datastax/nodejs-driver
Based on node-cassandra-cql
by Jorge Bay
Get it!
8
> npm install cassandra-driver
DataStax Ruby driver
9
https://github.com/datastax/ruby-driver
• Works with current OSS Cassandra
• Apache Licensed
Based on cql-rb
by Theo Hultberg (@iconara)
Get it!
10
> gem install cassandra-driver
DataStax Cassandra Drivers
• Load Balancing Policies
• Retry Policies
• Asynchronous
• Prepared statements
• Connection and cluster management
11
A Cassandra Driver should have…
On to the code!
• RESTful web server
• Need a few helpers
12
+ +
REST methods
• Operates on the “USERS” table in Cassandra
13
POST Insert a user
GET Select a user
PUT Update a user
DELETE Delete a user
CREATE TABLE users (
firstname text,
lastname text,
age int,
email text,
city text,
PRIMARY KEY (lastname)
);
14
Connection for NodeJS
• Express as the web server
• body-parser to get POST data
15
var client = new cassandra.Client({

contactPoints: ['127.0.0.1'],

keyspace: 'demo',

policies: {

retry: new cassandra.policies.retry.RetryPolicy(),

loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')

}

}

);
var express = require('express')

var bodyParser = require('body-parser');

var cassandra = require('cassandra-driver');
var client = new cassandra.Client({

contactPoints: ['127.0.0.1'],

keyspace: 'demo',

policies: {

retry: new cassandra.policies.retry.RetryPolicy(),

loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')

}

}

);
Connection for NodeJS
• Express as the web server
• body-parser to get POST data
16
var express = require('express')

var bodyParser = require('body-parser');

var cassandra = require('cassandra-driver');
var client = new cassandra.Client({

contactPoints: ['127.0.0.1'],

keyspace: 'demo',

policies: {

retry: new cassandra.policies.retry.RetryPolicy(),

loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')

}

}

);
Connection for NodeJS
• Express as the web server
• body-parser to get POST data
17
var express = require('express')

var bodyParser = require('body-parser');

var cassandra = require('cassandra-driver');
var client = new cassandra.Client({

contactPoints: ['127.0.0.1'],

keyspace: 'demo',

policies: {

retry: new cassandra.policies.retry.RetryPolicy(),

loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')

}

}

);
Connection for NodeJS
• Express as the web server
• body-parser to get POST data
18
var express = require('express')

var bodyParser = require('body-parser');

var cassandra = require('cassandra-driver');
Load balancing
19
Client 10.0.0.1
00-25
10.0.0.4
76-100
10.0.0.2
26-50
10.0.0.3
51-75
SELECT firstName
FROM users
WHERE lastname = ‘mills’;
datacenter1
datacenter1
Node Primary Replica Replica
10.0.0.1 00-25 76-100 51-75
10.0.0.2 26-50 00-25 76-100
10.0.0.3 51-75 26-50 00-25
10.0.0.4 76-100 51-75 26-50
loadBalancing: new DCAwareRoundRobinPolicy('datacenter1')
Insert a user with a POST
20
app.post('/users', function (req, res) {

var lastname = req.body.lastname;

var age = req.body.age;

var city = req.body.city;

var email = req.body.email;

var firstname = req.body.firstname;





var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";

var params = [lastname, age, city, email, firstname];



client.execute(query, params, {prepare: true}, function (err, result) {

if (!err) {

res.send("Inserted");

} else {

res.sendStatus(404)

}

})

})
Insert a user with a POST
21
app.post('/users', function (req, res) {

var lastname = req.body.lastname;

var age = req.body.age;

var city = req.body.city;

var email = req.body.email;

var firstname = req.body.firstname;





var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";

var params = [lastname, age, city, email, firstname];



client.execute(query, params, {prepare: true}, function (err, result) {

if (!err) {

res.send("Inserted");

} else {

res.sendStatus(404)

}

})

})
Insert a user with a POST
22
app.post('/users', function (req, res) {

var lastname = req.body.lastname;

var age = req.body.age;

var city = req.body.city;

var email = req.body.email;

var firstname = req.body.firstname;





var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";

var params = [lastname, age, city, email, firstname];



client.execute(query, params, {prepare: true}, function (err, result) {

if (!err) {

res.send("Inserted");

} else {

res.sendStatus(404)

}

})

})
Insert a user with a POST
23
app.post('/users', function (req, res) {

var lastname = req.body.lastname;

var age = req.body.age;

var city = req.body.city;

var email = req.body.email;

var firstname = req.body.firstname;





var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";

var params = [lastname, age, city, email, firstname];



client.execute(query, params, {prepare: true}, function (err, result) {

if (!err) {

res.send("Inserted");

} else {

res.sendStatus(404)

}

})

})
Select user with GET
24
app.get('/users/:lastname',function (req, res) {



var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";

var params = [req.params.lastname];

client.execute(query, params, {prepare: true}, function (err, result) {

if (!err){

if ( result.rows.length > 0 ) {

var user = result.rows[0];

console.log("name = %s, age = %d", user.firstname, user.age);

res.send(user)

} else {

res.sendStatus(404);

}

}

});

})
Select user with GET
25
app.get('/users/:lastname',function (req, res) {



var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";

var params = [req.params.lastname];

client.execute(query, params, {prepare: true}, function (err, result) {

if (!err){

if ( result.rows.length > 0 ) {

var user = result.rows[0];

console.log("name = %s, age = %d", user.firstname, user.age);

res.send(user)

} else {

res.sendStatus(404);

}

}

});

})
Select user with GET
26
app.get('/users/:lastname',function (req, res) {



var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";

var params = [req.params.lastname];

client.execute(query, params, {prepare: true}, function (err, result) {

if (!err){

if ( result.rows.length > 0 ) {

var user = result.rows[0];

console.log("name = %s, age = %d", user.firstname, user.age);

res.send(user)

} else {

res.sendStatus(404);

}

}

});

})
Select user with GET
27
app.get('/users/:lastname',function (req, res) {



var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";

var params = [req.params.lastname];

client.execute(query, params, {prepare: true}, function (err, result) {

if (!err){

if ( result.rows.length > 0 ) {

var user = result.rows[0];

console.log("name = %s, age = %d", user.firstname, user.age);

res.send(user)

} else {

res.sendStatus(404);

}

}

});

})
Select user with GET
28
app.get('/users/:lastname',function (req, res) {



var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";

var params = [req.params.lastname];

client.execute(query, params, {prepare: true}, function (err, result) {

if (!err){

if ( result.rows.length > 0 ) {

var user = result.rows[0];

console.log("name = %s, age = %d", user.firstname, user.age);

res.send(user)

} else {

res.sendStatus(404);

}

}

});

})
Update a user with PUT
29
app.put('/users/:lastname', function (req, res) {

var age = req.body.age;



console.log("lastname = " + req.params.lastname + ", age= " + age);



var query = "UPDATE users SET age = ? WHERE lastname = ?";

var params = [age, req.params.lastname];



client.execute(query, params, {prepare: true}, function (err, result) {

if (!err) {

res.send("Updated");

} else {

res.sendStatus(404)

}

});

})
Remove a user with DELETE
30
app.delete('/users/:lastname', function (req, res) {

var query = "DELETE FROM users WHERE lastname = ?";

var params = [req.params.lastname];



client.execute(query, params, {prepare: true}, function (err, result) {



if (!err) {

res.send("Deleted");

} else {

res.sendStatus(404)

}

});

})
31
Connection with Ruby
• Sinatra as the web server
• JSON for returning formatted results
32
cluster = Cassandra.cluster(

:hosts => ['127.0.01'],

:load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,

:retry_policy => Cassandra::Retry::Policies::Default.new,

logger: log)



keyspace = 'demo'

session = cluster.connect(keyspace)
require 'sinatra'

require 'JSON'

require 'cassandra'

require 'logger'
Connection with Ruby
• Sinatra as the web server
• JSON for returning formatted results
33
cluster = Cassandra.cluster(

:hosts => ['127.0.01'],

:load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,

:retry_policy => Cassandra::Retry::Policies::Default.new,

logger: log)



keyspace = 'demo'

session = cluster.connect(keyspace)
require 'sinatra'

require 'JSON'

require 'cassandra'

require 'logger'
Connection with Ruby
• Sinatra as the web server
• JSON for returning formatted results
34
cluster = Cassandra.cluster(

:hosts => ['127.0.01'],

:load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,

:retry_policy => Cassandra::Retry::Policies::Default.new,

logger: log)



keyspace = 'demo'

session = cluster.connect(keyspace)
require 'sinatra'

require 'JSON'

require 'cassandra'

require 'logger'
Retry Policies
• Retry requests on server errors
• Write Timeout
• Read Timeout
• Unavailable
35
Connection with Ruby
• Sinatra as the web server
• JSON for returning formatted results
36
cluster = Cassandra.cluster(

:hosts => ['127.0.01'],

:load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,

:retry_policy => Cassandra::Retry::Policies::Default.new,

logger: log)



keyspace = 'demo'

session = cluster.connect(keyspace)
require 'sinatra'

require 'JSON'

require 'cassandra'

require 'logger'
Insert a user with a POST
37
post '/users' do



begin

session.execute(userInsertStatement, :arguments => [params[:firstname], params[:lastname],
params[:age].to_i, params[:city], params[:email]])



"Inserted"



rescue Exception => e

log.error 'Error in insert a user'

log.error(e)

halt(404)

end



end
userInsertStatement = session.prepare("INSERT INTO users (firstname, lastname, age, city, email)
VALUES (?,?,?,?,?)")
Insert a user with a POST
38
post '/users' do



begin

session.execute(userInsertStatement, :arguments => [params[:firstname], params[:lastname],
params[:age].to_i, params[:city], params[:email]])



"Inserted"



rescue Exception => e

log.error 'Error in insert a user'

log.error(e)

halt(404)

end



end
userInsertStatement = session.prepare("INSERT INTO users (firstname, lastname, age, city, email)
VALUES (?,?,?,?,?)")
…
Insert a user with a POST
39
post '/users' do



begin

session.execute(userInsertStatement, :arguments => [params[:firstname], params[:lastname],
params[:age].to_i, params[:city], params[:email]])



"Inserted"



rescue Exception => e

log.error 'Error in insert a user'

log.error(e)

halt(404)

end



end
userInsertStatement = session.prepare("INSERT INTO users (firstname, lastname, age, city, email)
VALUES (?,?,?,?,?)")
…
Select user with GET
40
get '/users/:lastname' do



begin

result = session.execute(userSelectStatement, :arguments => [params[:lastname]])



if result.size < 1

halt(404)

end



result.first.to_json

rescue Exception => e

log.error 'Error in select a user'

log.error(e)

halt(404)

end



end
userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city
FROM users where lastname = ?")
Select user with GET
41
get '/users/:lastname' do



begin

result = session.execute(userSelectStatement, :arguments => [params[:lastname]])



if result.size < 1

halt(404)

end



result.first.to_json

rescue Exception => e

log.error 'Error in select a user'

log.error(e)

halt(404)

end



end
userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city
FROM users where lastname = ?")…
Select user with GET
42
get '/users/:lastname' do



begin

result = session.execute(userSelectStatement, :arguments => [params[:lastname]])



if result.size < 1

halt(404)

end



result.first.to_json

rescue Exception => e

log.error 'Error in select a user'

log.error(e)

halt(404)

end



end
userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city
FROM users where lastname = ?")
…
Select user with GET
43
get '/users/:lastname' do



begin

result = session.execute(userSelectStatement, :arguments => [params[:lastname]])



if result.size < 1

halt(404)

end



result.first.to_json

rescue Exception => e

log.error 'Error in select a user'

log.error(e)

halt(404)

end



end
userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city
FROM users where lastname = ?")
…
Quick note on Async
• Generates a Future
• Non-blocking until get
44
future = session.execute_async(statement)



# register success listener

future.on_success do |rows|

rows.each do |row|

puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"

end

end
Quick note on Async
• Generates a Future
• Non-blocking until get
45
future = session.execute_async(statement)



# register success listener

future.on_success do |rows|

rows.each do |row|

puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"

end

end
Quick note on Async
• Generates a Future
• Non-blocking until get
46
future = session.execute_async(statement)



# register success listener

future.on_success do |rows|

rows.each do |row|

puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"

end

end
Update a user with PUT
47
put '/users' do



begin

session.execute(userUpdateStatement, :arguments => [params[:age].to_i, params[:lastname]])



"Updated"



rescue Exception => e

log.error 'Error in update a user'

log.error(e)

halt(404)

end



end
userUpdateStatement = session.prepare("UPDATE users SET age = ? WHERE lastname = ?")
Remove a user with DELETE
48
delete '/users/:lastname' do



begin

session.execute(userDeleteStatement, :arguments => [params[:lastname]])



"Deleted"



rescue Exception => e

log.error 'Error in delete a user'

log.error(e)

halt(404)

end



end
userDeleteStatement = session.prepare("DELETE FROM users WHERE lastname = ?")
Made it!
49
Nice code.
Have a beer.
Get the code! Try yourself!
50
https://github.com/beccam/rest_server_ruby
https://github.com/beccam/rest_server_nodejs
NodeJS Code
Ruby Code
Questions?
Don’t forget to follow us on Twitter for more:
@RebccaMills
@PatrickMcFadin

More Related Content

What's hot

Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Codemotion
 
Cassandra Community Webinar | In Case of Emergency Break Glass
Cassandra Community Webinar | In Case of Emergency Break GlassCassandra Community Webinar | In Case of Emergency Break Glass
Cassandra Community Webinar | In Case of Emergency Break GlassDataStax
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017Andrus Adamchik
 
Cassandra 2.1
Cassandra 2.1Cassandra 2.1
Cassandra 2.1jbellis
 
Cassandra 2.0 better, faster, stronger
Cassandra 2.0   better, faster, strongerCassandra 2.0   better, faster, stronger
Cassandra 2.0 better, faster, strongerPatrick McFadin
 
Kick Your Database to the Curb
Kick Your Database to the CurbKick Your Database to the Curb
Kick Your Database to the CurbBill Bejeck
 
Cassandra EU - Data model on fire
Cassandra EU - Data model on fireCassandra EU - Data model on fire
Cassandra EU - Data model on firePatrick McFadin
 
Observability with Consul Connect
Observability with Consul ConnectObservability with Consul Connect
Observability with Consul ConnectBram Vogelaar
 
Tokyo cassandra conference 2014
Tokyo cassandra conference 2014Tokyo cassandra conference 2014
Tokyo cassandra conference 2014jbellis
 
Cassandra Summit 2013 Keynote
Cassandra Summit 2013 KeynoteCassandra Summit 2013 Keynote
Cassandra Summit 2013 Keynotejbellis
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015StampedeCon
 
Integrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applicationsIntegrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applicationslucenerevolution
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Codemotion
 
Advanced Apache Cassandra Operations with JMX
Advanced Apache Cassandra Operations with JMXAdvanced Apache Cassandra Operations with JMX
Advanced Apache Cassandra Operations with JMXzznate
 
PostgreSQL High-Availability and Geographic Locality using consul
PostgreSQL High-Availability and Geographic Locality using consulPostgreSQL High-Availability and Geographic Locality using consul
PostgreSQL High-Availability and Geographic Locality using consulSean Chittenden
 

What's hot (20)

From Node to Go
From Node to GoFrom Node to Go
From Node to Go
 
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
Building multi lingual and empatic bots - Sander van den Hoven - Codemotion A...
 
Cassandra Community Webinar | In Case of Emergency Break Glass
Cassandra Community Webinar | In Case of Emergency Break GlassCassandra Community Webinar | In Case of Emergency Break Glass
Cassandra Community Webinar | In Case of Emergency Break Glass
 
LinkRest at JeeConf 2017
LinkRest at JeeConf 2017LinkRest at JeeConf 2017
LinkRest at JeeConf 2017
 
Cassandra 2.1
Cassandra 2.1Cassandra 2.1
Cassandra 2.1
 
Cassandra 2.0 better, faster, stronger
Cassandra 2.0   better, faster, strongerCassandra 2.0   better, faster, stronger
Cassandra 2.0 better, faster, stronger
 
Kick Your Database to the Curb
Kick Your Database to the CurbKick Your Database to the Curb
Kick Your Database to the Curb
 
Cassandra EU - Data model on fire
Cassandra EU - Data model on fireCassandra EU - Data model on fire
Cassandra EU - Data model on fire
 
Observability with Consul Connect
Observability with Consul ConnectObservability with Consul Connect
Observability with Consul Connect
 
Tokyo cassandra conference 2014
Tokyo cassandra conference 2014Tokyo cassandra conference 2014
Tokyo cassandra conference 2014
 
Cassandra Summit 2013 Keynote
Cassandra Summit 2013 KeynoteCassandra Summit 2013 Keynote
Cassandra Summit 2013 Keynote
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015
 
CQL3 in depth
CQL3 in depthCQL3 in depth
CQL3 in depth
 
Cassandra 2.2 & 3.0
Cassandra 2.2 & 3.0Cassandra 2.2 & 3.0
Cassandra 2.2 & 3.0
 
Integrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applicationsIntegrate Solr with real-time stream processing applications
Integrate Solr with real-time stream processing applications
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
MySQL under the siege
MySQL under the siegeMySQL under the siege
MySQL under the siege
 
Time series databases
Time series databasesTime series databases
Time series databases
 
Advanced Apache Cassandra Operations with JMX
Advanced Apache Cassandra Operations with JMXAdvanced Apache Cassandra Operations with JMX
Advanced Apache Cassandra Operations with JMX
 
PostgreSQL High-Availability and Geographic Locality using consul
PostgreSQL High-Availability and Geographic Locality using consulPostgreSQL High-Availability and Geographic Locality using consul
PostgreSQL High-Availability and Geographic Locality using consul
 

Similar to Cassandra Day Chicago 2015: 0 to App Faster with Node.js and Ruby

DataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax Academy
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013Laurent_VB
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015NoSQLmatters
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hacksteindistributed matters
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Morris Singer
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.jsFDConf
 
FwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsFwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsTimur Shemsedinov
 
GraphQL Bangkok Meetup 2.0
GraphQL Bangkok Meetup 2.0GraphQL Bangkok Meetup 2.0
GraphQL Bangkok Meetup 2.0Tobias Meixner
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with ExpressAaron Stannard
 
node.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.ionode.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.ioSteven Beeckman
 
Building your first Node app with Connect & Express
Building your first Node app with Connect & ExpressBuilding your first Node app with Connect & Express
Building your first Node app with Connect & ExpressChristian Joudrey
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Joe Keeley
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
Node js introduction
Node js introductionNode js introduction
Node js introductionAlex Su
 
Microservices using Node.js and RabbitMQ
Microservices using Node.js and RabbitMQMicroservices using Node.js and RabbitMQ
Microservices using Node.js and RabbitMQCarolina Pascale Campos
 

Similar to Cassandra Day Chicago 2015: 0 to App Faster with Node.js and Ruby (20)

DataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJSDataStax: 0 to App faster with Ruby and NodeJS
DataStax: 0 to App faster with Ruby and NodeJS
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
Express JS
Express JSExpress JS
Express JS
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
NoSQL meets Microservices
NoSQL meets MicroservicesNoSQL meets Microservices
NoSQL meets Microservices
 
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
Michael Hackstein - NoSQL meets Microservices - NoSQL matters Dublin 2015
 
NoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael HacksteinNoSQL meets Microservices - Michael Hackstein
NoSQL meets Microservices - Michael Hackstein
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
 
Writing RESTful web services using Node.js
Writing RESTful web services using Node.jsWriting RESTful web services using Node.js
Writing RESTful web services using Node.js
 
FwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.jsFwDays 2021: Metarhia Technology Stack for Node.js
FwDays 2021: Metarhia Technology Stack for Node.js
 
GraphQL Bangkok Meetup 2.0
GraphQL Bangkok Meetup 2.0GraphQL Bangkok Meetup 2.0
GraphQL Bangkok Meetup 2.0
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
node.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.ionode.js and the AR.Drone: building a real-time dashboard using socket.io
node.js and the AR.Drone: building a real-time dashboard using socket.io
 
Building your first Node app with Connect & Express
Building your first Node app with Connect & ExpressBuilding your first Node app with Connect & Express
Building your first Node app with Connect & Express
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Intro to Ember.JS 2016
Intro to Ember.JS 2016Intro to Ember.JS 2016
Intro to Ember.JS 2016
 
Node js introduction
Node js introductionNode js introduction
Node js introduction
 
Microservices using Node.js and RabbitMQ
Microservices using Node.js and RabbitMQMicroservices using Node.js and RabbitMQ
Microservices using Node.js and RabbitMQ
 

More from DataStax Academy

Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftForrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftDataStax Academy
 
Introduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseIntroduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseDataStax Academy
 
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraIntroduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraDataStax Academy
 
Cassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsCassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsDataStax Academy
 
Cassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingCassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingDataStax Academy
 
Cassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackCassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackDataStax Academy
 
Data Modeling for Apache Cassandra
Data Modeling for Apache CassandraData Modeling for Apache Cassandra
Data Modeling for Apache CassandraDataStax Academy
 
Production Ready Cassandra
Production Ready CassandraProduction Ready Cassandra
Production Ready CassandraDataStax Academy
 
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonCassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonDataStax Academy
 
Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1DataStax Academy
 
Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2DataStax Academy
 
Standing Up Your First Cluster
Standing Up Your First ClusterStanding Up Your First Cluster
Standing Up Your First ClusterDataStax Academy
 
Real Time Analytics with Dse
Real Time Analytics with DseReal Time Analytics with Dse
Real Time Analytics with DseDataStax Academy
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraDataStax Academy
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseDataStax Academy
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraDataStax Academy
 

More from DataStax Academy (20)

Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craftForrester CXNYC 2017 - Delivering great real-time cx is a true craft
Forrester CXNYC 2017 - Delivering great real-time cx is a true craft
 
Introduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph DatabaseIntroduction to DataStax Enterprise Graph Database
Introduction to DataStax Enterprise Graph Database
 
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache CassandraIntroduction to DataStax Enterprise Advanced Replication with Apache Cassandra
Introduction to DataStax Enterprise Advanced Replication with Apache Cassandra
 
Cassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart LabsCassandra on Docker @ Walmart Labs
Cassandra on Docker @ Walmart Labs
 
Cassandra 3.0 Data Modeling
Cassandra 3.0 Data ModelingCassandra 3.0 Data Modeling
Cassandra 3.0 Data Modeling
 
Cassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stackCassandra Adoption on Cisco UCS & Open stack
Cassandra Adoption on Cisco UCS & Open stack
 
Data Modeling for Apache Cassandra
Data Modeling for Apache CassandraData Modeling for Apache Cassandra
Data Modeling for Apache Cassandra
 
Coursera Cassandra Driver
Coursera Cassandra DriverCoursera Cassandra Driver
Coursera Cassandra Driver
 
Production Ready Cassandra
Production Ready CassandraProduction Ready Cassandra
Production Ready Cassandra
 
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & PythonCassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
Cassandra @ Netflix: Monitoring C* at Scale, Gossip and Tickler & Python
 
Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1Cassandra @ Sony: The good, the bad, and the ugly part 1
Cassandra @ Sony: The good, the bad, and the ugly part 1
 
Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2Cassandra @ Sony: The good, the bad, and the ugly part 2
Cassandra @ Sony: The good, the bad, and the ugly part 2
 
Standing Up Your First Cluster
Standing Up Your First ClusterStanding Up Your First Cluster
Standing Up Your First Cluster
 
Real Time Analytics with Dse
Real Time Analytics with DseReal Time Analytics with Dse
Real Time Analytics with Dse
 
Introduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache CassandraIntroduction to Data Modeling with Apache Cassandra
Introduction to Data Modeling with Apache Cassandra
 
Cassandra Core Concepts
Cassandra Core ConceptsCassandra Core Concepts
Cassandra Core Concepts
 
Enabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax EnterpriseEnabling Search in your Cassandra Application with DataStax Enterprise
Enabling Search in your Cassandra Application with DataStax Enterprise
 
Bad Habits Die Hard
Bad Habits Die Hard Bad Habits Die Hard
Bad Habits Die Hard
 
Advanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache CassandraAdvanced Data Modeling with Apache Cassandra
Advanced Data Modeling with Apache Cassandra
 
Advanced Cassandra
Advanced CassandraAdvanced Cassandra
Advanced Cassandra
 

Recently uploaded

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governanceWSO2
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaWSO2
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseWSO2
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistandanishmna97
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformWSO2
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringWSO2
 

Recently uploaded (20)

"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governance
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using Ballerina
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Navigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern EnterpriseNavigating Identity and Access Management in the Modern Enterprise
Navigating Identity and Access Management in the Modern Enterprise
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 

Cassandra Day Chicago 2015: 0 to App Faster with Node.js and Ruby

  • 1. 0 to App faster with NodeJS and Ruby Rebecca Mills @RebccaMills Patrick McFadin @PatrickMcFadin
  • 2. The situation • REST interface to Cassandra data • Support CRUD operations • It’s Friday and… 2 Umm yeah, and I’m going to need that by Monday morning.
  • 3. Choose your language • Support for all Cassandra features • Easy to work with • Performant 3
  • 5. 5
  • 6. Need to get this done now 6
  • 7. DataStax NodeJS driver • Works with current OSS Cassandra • Apache Licensed 7 https://github.com/datastax/nodejs-driver Based on node-cassandra-cql by Jorge Bay
  • 8. Get it! 8 > npm install cassandra-driver
  • 9. DataStax Ruby driver 9 https://github.com/datastax/ruby-driver • Works with current OSS Cassandra • Apache Licensed Based on cql-rb by Theo Hultberg (@iconara)
  • 10. Get it! 10 > gem install cassandra-driver
  • 11. DataStax Cassandra Drivers • Load Balancing Policies • Retry Policies • Asynchronous • Prepared statements • Connection and cluster management 11 A Cassandra Driver should have…
  • 12. On to the code! • RESTful web server • Need a few helpers 12 + +
  • 13. REST methods • Operates on the “USERS” table in Cassandra 13 POST Insert a user GET Select a user PUT Update a user DELETE Delete a user CREATE TABLE users ( firstname text, lastname text, age int, email text, city text, PRIMARY KEY (lastname) );
  • 14. 14
  • 15. Connection for NodeJS • Express as the web server • body-parser to get POST data 15 var client = new cassandra.Client({
 contactPoints: ['127.0.0.1'],
 keyspace: 'demo',
 policies: {
 retry: new cassandra.policies.retry.RetryPolicy(),
 loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')
 }
 }
 ); var express = require('express')
 var bodyParser = require('body-parser');
 var cassandra = require('cassandra-driver');
  • 16. var client = new cassandra.Client({
 contactPoints: ['127.0.0.1'],
 keyspace: 'demo',
 policies: {
 retry: new cassandra.policies.retry.RetryPolicy(),
 loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')
 }
 }
 ); Connection for NodeJS • Express as the web server • body-parser to get POST data 16 var express = require('express')
 var bodyParser = require('body-parser');
 var cassandra = require('cassandra-driver');
  • 17. var client = new cassandra.Client({
 contactPoints: ['127.0.0.1'],
 keyspace: 'demo',
 policies: {
 retry: new cassandra.policies.retry.RetryPolicy(),
 loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')
 }
 }
 ); Connection for NodeJS • Express as the web server • body-parser to get POST data 17 var express = require('express')
 var bodyParser = require('body-parser');
 var cassandra = require('cassandra-driver');
  • 18. var client = new cassandra.Client({
 contactPoints: ['127.0.0.1'],
 keyspace: 'demo',
 policies: {
 retry: new cassandra.policies.retry.RetryPolicy(),
 loadBalancing: new cassandra.policies.loadBalancing.DCAwareRoundRobinPolicy('datacenter1')
 }
 }
 ); Connection for NodeJS • Express as the web server • body-parser to get POST data 18 var express = require('express')
 var bodyParser = require('body-parser');
 var cassandra = require('cassandra-driver');
  • 19. Load balancing 19 Client 10.0.0.1 00-25 10.0.0.4 76-100 10.0.0.2 26-50 10.0.0.3 51-75 SELECT firstName FROM users WHERE lastname = ‘mills’; datacenter1 datacenter1 Node Primary Replica Replica 10.0.0.1 00-25 76-100 51-75 10.0.0.2 26-50 00-25 76-100 10.0.0.3 51-75 26-50 00-25 10.0.0.4 76-100 51-75 26-50 loadBalancing: new DCAwareRoundRobinPolicy('datacenter1')
  • 20. Insert a user with a POST 20 app.post('/users', function (req, res) {
 var lastname = req.body.lastname;
 var age = req.body.age;
 var city = req.body.city;
 var email = req.body.email;
 var firstname = req.body.firstname;
 
 
 var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";
 var params = [lastname, age, city, email, firstname];
 
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err) {
 res.send("Inserted");
 } else {
 res.sendStatus(404)
 }
 })
 })
  • 21. Insert a user with a POST 21 app.post('/users', function (req, res) {
 var lastname = req.body.lastname;
 var age = req.body.age;
 var city = req.body.city;
 var email = req.body.email;
 var firstname = req.body.firstname;
 
 
 var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";
 var params = [lastname, age, city, email, firstname];
 
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err) {
 res.send("Inserted");
 } else {
 res.sendStatus(404)
 }
 })
 })
  • 22. Insert a user with a POST 22 app.post('/users', function (req, res) {
 var lastname = req.body.lastname;
 var age = req.body.age;
 var city = req.body.city;
 var email = req.body.email;
 var firstname = req.body.firstname;
 
 
 var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";
 var params = [lastname, age, city, email, firstname];
 
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err) {
 res.send("Inserted");
 } else {
 res.sendStatus(404)
 }
 })
 })
  • 23. Insert a user with a POST 23 app.post('/users', function (req, res) {
 var lastname = req.body.lastname;
 var age = req.body.age;
 var city = req.body.city;
 var email = req.body.email;
 var firstname = req.body.firstname;
 
 
 var query = "INSERT INTO users (lastname, age, city, email, firstname) VALUES ( ?,?,?,?,?)";
 var params = [lastname, age, city, email, firstname];
 
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err) {
 res.send("Inserted");
 } else {
 res.sendStatus(404)
 }
 })
 })
  • 24. Select user with GET 24 app.get('/users/:lastname',function (req, res) {
 
 var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";
 var params = [req.params.lastname];
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err){
 if ( result.rows.length > 0 ) {
 var user = result.rows[0];
 console.log("name = %s, age = %d", user.firstname, user.age);
 res.send(user)
 } else {
 res.sendStatus(404);
 }
 }
 });
 })
  • 25. Select user with GET 25 app.get('/users/:lastname',function (req, res) {
 
 var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";
 var params = [req.params.lastname];
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err){
 if ( result.rows.length > 0 ) {
 var user = result.rows[0];
 console.log("name = %s, age = %d", user.firstname, user.age);
 res.send(user)
 } else {
 res.sendStatus(404);
 }
 }
 });
 })
  • 26. Select user with GET 26 app.get('/users/:lastname',function (req, res) {
 
 var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";
 var params = [req.params.lastname];
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err){
 if ( result.rows.length > 0 ) {
 var user = result.rows[0];
 console.log("name = %s, age = %d", user.firstname, user.age);
 res.send(user)
 } else {
 res.sendStatus(404);
 }
 }
 });
 })
  • 27. Select user with GET 27 app.get('/users/:lastname',function (req, res) {
 
 var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";
 var params = [req.params.lastname];
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err){
 if ( result.rows.length > 0 ) {
 var user = result.rows[0];
 console.log("name = %s, age = %d", user.firstname, user.age);
 res.send(user)
 } else {
 res.sendStatus(404);
 }
 }
 });
 })
  • 28. Select user with GET 28 app.get('/users/:lastname',function (req, res) {
 
 var query = "SELECT lastname, age, city, email, firstname FROM users WHERE lastname= ?";
 var params = [req.params.lastname];
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err){
 if ( result.rows.length > 0 ) {
 var user = result.rows[0];
 console.log("name = %s, age = %d", user.firstname, user.age);
 res.send(user)
 } else {
 res.sendStatus(404);
 }
 }
 });
 })
  • 29. Update a user with PUT 29 app.put('/users/:lastname', function (req, res) {
 var age = req.body.age;
 
 console.log("lastname = " + req.params.lastname + ", age= " + age);
 
 var query = "UPDATE users SET age = ? WHERE lastname = ?";
 var params = [age, req.params.lastname];
 
 client.execute(query, params, {prepare: true}, function (err, result) {
 if (!err) {
 res.send("Updated");
 } else {
 res.sendStatus(404)
 }
 });
 })
  • 30. Remove a user with DELETE 30 app.delete('/users/:lastname', function (req, res) {
 var query = "DELETE FROM users WHERE lastname = ?";
 var params = [req.params.lastname];
 
 client.execute(query, params, {prepare: true}, function (err, result) {
 
 if (!err) {
 res.send("Deleted");
 } else {
 res.sendStatus(404)
 }
 });
 })
  • 31. 31
  • 32. Connection with Ruby • Sinatra as the web server • JSON for returning formatted results 32 cluster = Cassandra.cluster(
 :hosts => ['127.0.01'],
 :load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,
 :retry_policy => Cassandra::Retry::Policies::Default.new,
 logger: log)
 
 keyspace = 'demo'
 session = cluster.connect(keyspace) require 'sinatra'
 require 'JSON'
 require 'cassandra'
 require 'logger'
  • 33. Connection with Ruby • Sinatra as the web server • JSON for returning formatted results 33 cluster = Cassandra.cluster(
 :hosts => ['127.0.01'],
 :load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,
 :retry_policy => Cassandra::Retry::Policies::Default.new,
 logger: log)
 
 keyspace = 'demo'
 session = cluster.connect(keyspace) require 'sinatra'
 require 'JSON'
 require 'cassandra'
 require 'logger'
  • 34. Connection with Ruby • Sinatra as the web server • JSON for returning formatted results 34 cluster = Cassandra.cluster(
 :hosts => ['127.0.01'],
 :load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,
 :retry_policy => Cassandra::Retry::Policies::Default.new,
 logger: log)
 
 keyspace = 'demo'
 session = cluster.connect(keyspace) require 'sinatra'
 require 'JSON'
 require 'cassandra'
 require 'logger'
  • 35. Retry Policies • Retry requests on server errors • Write Timeout • Read Timeout • Unavailable 35
  • 36. Connection with Ruby • Sinatra as the web server • JSON for returning formatted results 36 cluster = Cassandra.cluster(
 :hosts => ['127.0.01'],
 :load_balancing_policy => Cassandra::LoadBalancing::Policies::RoundRobin.new,
 :retry_policy => Cassandra::Retry::Policies::Default.new,
 logger: log)
 
 keyspace = 'demo'
 session = cluster.connect(keyspace) require 'sinatra'
 require 'JSON'
 require 'cassandra'
 require 'logger'
  • 37. Insert a user with a POST 37 post '/users' do
 
 begin
 session.execute(userInsertStatement, :arguments => [params[:firstname], params[:lastname], params[:age].to_i, params[:city], params[:email]])
 
 "Inserted"
 
 rescue Exception => e
 log.error 'Error in insert a user'
 log.error(e)
 halt(404)
 end
 
 end userInsertStatement = session.prepare("INSERT INTO users (firstname, lastname, age, city, email) VALUES (?,?,?,?,?)")
  • 38. Insert a user with a POST 38 post '/users' do
 
 begin
 session.execute(userInsertStatement, :arguments => [params[:firstname], params[:lastname], params[:age].to_i, params[:city], params[:email]])
 
 "Inserted"
 
 rescue Exception => e
 log.error 'Error in insert a user'
 log.error(e)
 halt(404)
 end
 
 end userInsertStatement = session.prepare("INSERT INTO users (firstname, lastname, age, city, email) VALUES (?,?,?,?,?)") …
  • 39. Insert a user with a POST 39 post '/users' do
 
 begin
 session.execute(userInsertStatement, :arguments => [params[:firstname], params[:lastname], params[:age].to_i, params[:city], params[:email]])
 
 "Inserted"
 
 rescue Exception => e
 log.error 'Error in insert a user'
 log.error(e)
 halt(404)
 end
 
 end userInsertStatement = session.prepare("INSERT INTO users (firstname, lastname, age, city, email) VALUES (?,?,?,?,?)") …
  • 40. Select user with GET 40 get '/users/:lastname' do
 
 begin
 result = session.execute(userSelectStatement, :arguments => [params[:lastname]])
 
 if result.size < 1
 halt(404)
 end
 
 result.first.to_json
 rescue Exception => e
 log.error 'Error in select a user'
 log.error(e)
 halt(404)
 end
 
 end userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city FROM users where lastname = ?")
  • 41. Select user with GET 41 get '/users/:lastname' do
 
 begin
 result = session.execute(userSelectStatement, :arguments => [params[:lastname]])
 
 if result.size < 1
 halt(404)
 end
 
 result.first.to_json
 rescue Exception => e
 log.error 'Error in select a user'
 log.error(e)
 halt(404)
 end
 
 end userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city FROM users where lastname = ?")…
  • 42. Select user with GET 42 get '/users/:lastname' do
 
 begin
 result = session.execute(userSelectStatement, :arguments => [params[:lastname]])
 
 if result.size < 1
 halt(404)
 end
 
 result.first.to_json
 rescue Exception => e
 log.error 'Error in select a user'
 log.error(e)
 halt(404)
 end
 
 end userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city FROM users where lastname = ?") …
  • 43. Select user with GET 43 get '/users/:lastname' do
 
 begin
 result = session.execute(userSelectStatement, :arguments => [params[:lastname]])
 
 if result.size < 1
 halt(404)
 end
 
 result.first.to_json
 rescue Exception => e
 log.error 'Error in select a user'
 log.error(e)
 halt(404)
 end
 
 end userSelectStatement = session.prepare("SELECT firstname,lastname, age, email, city FROM users where lastname = ?") …
  • 44. Quick note on Async • Generates a Future • Non-blocking until get 44 future = session.execute_async(statement)
 
 # register success listener
 future.on_success do |rows|
 rows.each do |row|
 puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"
 end
 end
  • 45. Quick note on Async • Generates a Future • Non-blocking until get 45 future = session.execute_async(statement)
 
 # register success listener
 future.on_success do |rows|
 rows.each do |row|
 puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"
 end
 end
  • 46. Quick note on Async • Generates a Future • Non-blocking until get 46 future = session.execute_async(statement)
 
 # register success listener
 future.on_success do |rows|
 rows.each do |row|
 puts "#{row["artist"]}: #{row["title"]} / #{row["album"]}"
 end
 end
  • 47. Update a user with PUT 47 put '/users' do
 
 begin
 session.execute(userUpdateStatement, :arguments => [params[:age].to_i, params[:lastname]])
 
 "Updated"
 
 rescue Exception => e
 log.error 'Error in update a user'
 log.error(e)
 halt(404)
 end
 
 end userUpdateStatement = session.prepare("UPDATE users SET age = ? WHERE lastname = ?")
  • 48. Remove a user with DELETE 48 delete '/users/:lastname' do
 
 begin
 session.execute(userDeleteStatement, :arguments => [params[:lastname]])
 
 "Deleted"
 
 rescue Exception => e
 log.error 'Error in delete a user'
 log.error(e)
 halt(404)
 end
 
 end userDeleteStatement = session.prepare("DELETE FROM users WHERE lastname = ?")
  • 50. Get the code! Try yourself! 50 https://github.com/beccam/rest_server_ruby https://github.com/beccam/rest_server_nodejs NodeJS Code Ruby Code
  • 51. Questions? Don’t forget to follow us on Twitter for more: @RebccaMills @PatrickMcFadin