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 NodeJS and Ruby to App faster with Cassandra

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 NodeJS and Ruby to App faster with Cassandra (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
 

Recently uploaded

Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 

Recently uploaded (20)

Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 

NodeJS and Ruby to App faster with Cassandra

  • 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