SlideShare a Scribd company logo
Where little posts make a mighty magazine. Where readers become editors. Where giving inspiration is rewarded.
From world
to
The task:
Backend for real-time
communication app
Why Ruby?
2011
Elegant language &
environment
1. Beautiful Language: Dynamic, OO, linear
##
# Distribute a system message
#
def find_and_distribute(message_id)
message = Message.find(message_id)
raise SystemError, "Message not found" if message.nil?
message.start_distribution
return message.to_json
rescue SystemError
log.error "[API] distribute fail: "#{e.message}”
end
1. Beautiful Language: Dynamic, OO, linear
2. Super ORM/ODM: ActiveRecord & Mongoid
Elegant language &
environment
class MediaRobotUser
include Mongoid::Document
# schema
field :rss_url, type: String
field :updated, type: DateTime
field :update_freq, type: Integer, default: 5
# Validations
validates :rss_url, :presence => true
validates :update_freq, :presence => true
def activate_user
robot_queue = ”robot_update_#{self.id.to_s}"
Resque.remove_schedule(robot_queue)
schedule_options =
{ 'every' => '15m',
'custom_job_class' => “Bot::Jobs::UpdateMediaRobot",
'queue' => :update_media_robot,
'args' => self.id.to_s,
}
Resque.set_schedule(robot_queue, schedule_options)
end
end # class MediaRobotUser
1. Beautiful Language: Dynamic, OO, linear
2. Super ORM/ODM: ActiveRecord & Mongoid
3. Robust libraries: Community focus on libs selected for Rails
Elegant language &
environment
From Ruby to Node.js
1. Beautiful Language: Dynamic, OO, linear
2. Super ORM/ODM: ActiveRecord & Mongoid
3. Robust libraries: Rails gives focus on library development
4. Killer server stack for API: Thin + Rack + Sinatra
Elegant language &
environment
Dedicated async web server for Ruby apps
Instead of complex Apache/Passenger setup, you
download thin and just run your app with it.
Layer between web servers and web frameworks
De facto standard in Ruby world: choose any ruby
web server, choose any ruby framework, throw
own middleware into soup and it just works!
Simple HTTP request handler on top of Rack
No MVC bloat for a simple, RESTful API
application, but want still use same robust libraries
Rails apps use. Just write functionality for your
GET /my/api endpoint and go!
# Set Rails session to OAuth2 access token convert middleware
use Auth::RailsSessionConverter
# Set OAuth2 handler
use Rack::OAuth2::Server
# launch Sinatra REST API server
require File.dirname(__FILE__) + '/app/access/restapi'
map('/rest/vp5/') { run Access::RESTAPI }
2. Define Rack configuration (e.g. myrack.ru):
3. Run web server:
1. Write Sinatra web app:
##
# API call to get backend version.
#
get '/system/version' do
authenticate!('int_api_user')
content_type :json
status 200
return (JSON :data_api_version => 'proto v5.0')
end
$ bundle exec thin –R myrack.ru –p 9400 -e development start
Ruby ≠ Rails! Sinatra,
Resque and many other
cool frameworks
Could map
other apps to
different paths
“homemade”
middleware block
hooked in!
No fuzz
The next task:
Backend for Media App
2013
So.. Let’s think about
Culture for
unsecure
code?
Born in
2011 – are
the libs
there?
Don’t want
that callback
spaghetti!
DB drivers
and
ODMs?Performance
?
How to keep
running in
production?
/**
* Static content delivery
*/
staticDelivery: function (req, res) {
var tmpDir = lzconf.filedbdir + "/tmp";
file.mkdir(tmpDir, '777’, function() {
var fileSource = lzconf.filedbdir + "/" + req.params[0];
// do the work
easyimg.rescrop(options, function(err, image) {
console.log('Resized and cropped: ', image);
// send file
res.sendfile(tmpTarget, {maxAge: 604800}, function(err) {
if (err) { … }
// remove temp file
fs.unlink(tmpTarget, function(err, success) {
…
});
});
});
});
}
function myApiFunc(callback)
{
/*
* This pattern does NOT work!
*/
try {
doSomeAsynchronousOperation(function (err) {
if (err)
throw (err);
/* continue as normal */
});
} catch (ex) {
callback(ex);
}
}
Source: http://www.joyent.com/developers/node/design/errors
Whaaat?
Cannot use
try…catch??
“Sadly, that seems to be the story of
Node.JS and the frameworks that use it.
Derby, Meteor, SocketStream– they all are
relatively new and immature, and in some
cases, lack critical functionality of a web
framework or have serious issues with
security. That sort of puts me, as a
developer, in an odd position. I’ve
determined Node.JS is a good platform for a
project, but without reinventing the wheel,
what framework do I use to speed up
development?”
– Andrew Munsell
https://www.andrewmunsell.com/blog/the-odd-
state-of-nodejs-and-its-frameworks
From Ruby to Node.js
“Sinatra inspired web development
framework for node.js – insanely fast,
flexible, and simple.”
Yes!
Powered by Connect
More over,
future looked
promising:
“Next generation web framework
for node js.”
Why it rocks
ECMAScript 6: Generators
$ node --harmony
> function* giveMeFruit() {
... yield "apple";
... yield "banana";
... }
> var fruitMachine = giveMeFruit()
> fruitMachine.next()
{ value: 'apple', done: false }
> fruitMachine.next()
{ value: 'banana', done: false }
> fruitMachine.next()
{ value: undefined, done: true }
> fruitMachine.next()
Error: Generator has already finished
at GeneratorFunctionPrototype.next (native)
…
What an earth
this has to do
with a HTTP
framework?
Why it rocks
co– “The ultimate generator based flow-
control goodness for nodejs (supports thunks,
promises, etc)”
var co = require('co');
co(function *(){
console.log(“updating user...”);
try {
var user = yield Users.findOneById(‘123’).exec();
if (!user) throw new Error(“Cannot find user”);
user.name = “juha”;
yield Promise.promisify(user.save, user)();
} catch (err) {
console.log(“Name update failed: ”, err);
}
})()
This Mongoose
finder returns a
promise by default
“Save” need to be
transferred into
promise first for
yield
Try…catch as it
should be 
Generator flow control (co)
is the heart of Koa server
Why it rocks
var koa = require('koa’)
, api = require('./v1/myApiModule’), ...
app.use(mount(‘/api/v1’, api));
app.listen(8080);
Why it rocks
Additional middleware to
handle routing, e.g. koa-
mount
Custom middleware
upstream &
downstream
app.use(function *(next) {
var start = new Date;
yield next;
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
});
Many needed middleware
libs already ported, such as
* koa-session-mongo
* koa-passport
* koa-cors
* koa-send
app.use(session());
app.use(passport.username());
app.use(function *(next) {
try {
yield next;
} catch (err) {
this.status = err.status || 500;
}
})
More robust code
API
with koa-router
Why it rocks
var Router = require('koa-router')
var API = new Router()
API.get('/topics/:topicId', function *() {
try {
this.body = yield MySubSystem.getTopic({
id: this.params.topicId,
filter: this.request.query.filter_by
});
} catch (err) {
if (err.name === "DocumentNotFoundError") {
this.body = "Topic not found";
this.status = 404;
} else {
throw err;
}
}
}
Why it rocks
From Ruby to Node.js
From Ruby to Node.js
Where little posts make a mighty magazine. Where readers become editors. Where giving inspiration is rewarded.
Thank you!

More Related Content

KEY
Rails web api 开发
KEY
More to RoC weibo
PPTX
What the rack
PPTX
REST APIs in Laravel 101
PDF
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
PDF
JWT - Sécurisez vos APIs
PPT
Real Time Communication using Node.js and Socket.io
PDF
Rails web api 开发
More to RoC weibo
What the rack
REST APIs in Laravel 101
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
JWT - Sécurisez vos APIs
Real Time Communication using Node.js and Socket.io

What's hot (20)

KEY
Going real time with Socket.io
PDF
Using Sinatra to Build REST APIs in Ruby
PDF
Build REST API clients for AngularJS
ODP
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
PDF
Bootstrat REST APIs with Laravel 5
PPT
Building Single Page Application (SPA) with Symfony2 and AngularJS
PDF
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
PDF
Inside Bokete: Web Application with Mojolicious and others
PPTX
PPTX
Building Web Apps with Express
PDF
Ruby HTTP clients comparison
PDF
Socket.io (part 1)
PPTX
Node.js Express
PPTX
Express js
PPTX
Intro to Node
KEY
Silex, the microframework
PDF
Express node js
KEY
Socket.io
ODP
REST API Laravel
PDF
Developing apps using Perl
Going real time with Socket.io
Using Sinatra to Build REST APIs in Ruby
Build REST API clients for AngularJS
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Bootstrat REST APIs with Laravel 5
Building Single Page Application (SPA) with Symfony2 and AngularJS
[PHP 也有 Day] 垃圾留言守城記 - 用 Laravel 阻擋 SPAM 留言的奮鬥史
Inside Bokete: Web Application with Mojolicious and others
Building Web Apps with Express
Ruby HTTP clients comparison
Socket.io (part 1)
Node.js Express
Express js
Intro to Node
Silex, the microframework
Express node js
Socket.io
REST API Laravel
Developing apps using Perl
Ad

Similar to From Ruby to Node.js (20)

PDF
soft-shake.ch - Hands on Node.js
PPTX
PDF
Day In A Life Of A Node.js Developer
PDF
Day in a life of a node.js developer
PDF
Node.js - async for the rest of us.
KEY
Writing robust Node.js applications
PPT
RESTful API In Node Js using Express
PDF
Original slides from Ryan Dahl's NodeJs intro talk
PPTX
Electron - cross platform desktop applications made easy
PPTX
Introduction to Node.js
PDF
Node.js vs Play Framework
PDF
Porting Rails Apps to High Availability Systems
PDF
Docker serverless v1.0
KEY
Intro to PSGI and Plack
PPTX
Real World Lessons on the Pain Points of Node.JS Application
PDF
A Closer Look At React Native
PDF
Nodejs Explained with Examples
PDF
Nodejsexplained 101116115055-phpapp02
PDF
MongoDB World 2018: Tutorial - Got Dibs? Building a Real-Time Bidding App wit...
PDF
Phoenix for Rails Devs
soft-shake.ch - Hands on Node.js
Day In A Life Of A Node.js Developer
Day in a life of a node.js developer
Node.js - async for the rest of us.
Writing robust Node.js applications
RESTful API In Node Js using Express
Original slides from Ryan Dahl's NodeJs intro talk
Electron - cross platform desktop applications made easy
Introduction to Node.js
Node.js vs Play Framework
Porting Rails Apps to High Availability Systems
Docker serverless v1.0
Intro to PSGI and Plack
Real World Lessons on the Pain Points of Node.JS Application
A Closer Look At React Native
Nodejs Explained with Examples
Nodejsexplained 101116115055-phpapp02
MongoDB World 2018: Tutorial - Got Dibs? Building a Real-Time Bidding App wit...
Phoenix for Rails Devs
Ad

Recently uploaded (20)

PPT
Introduction Database Management System for Course Database
PDF
Understanding Forklifts - TECH EHS Solution
PDF
medical staffing services at VALiNTRY
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
ISO 45001 Occupational Health and Safety Management System
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
ManageIQ - Sprint 268 Review - Slide Deck
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
top salesforce developer skills in 2025.pdf
PDF
Nekopoi APK 2025 free lastest update
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
L1 - Introduction to python Backend.pptx
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
System and Network Administration Chapter 2
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
Introduction Database Management System for Course Database
Understanding Forklifts - TECH EHS Solution
medical staffing services at VALiNTRY
Odoo POS Development Services by CandidRoot Solutions
ISO 45001 Occupational Health and Safety Management System
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
ManageIQ - Sprint 268 Review - Slide Deck
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Navsoft: AI-Powered Business Solutions & Custom Software Development
top salesforce developer skills in 2025.pdf
Nekopoi APK 2025 free lastest update
Upgrade and Innovation Strategies for SAP ERP Customers
L1 - Introduction to python Backend.pptx
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
How Creative Agencies Leverage Project Management Software.pdf
System and Network Administration Chapter 2
Softaken Excel to vCard Converter Software.pdf
Design an Analysis of Algorithms I-SECS-1021-03

From Ruby to Node.js

  • 1. Where little posts make a mighty magazine. Where readers become editors. Where giving inspiration is rewarded. From world to
  • 2. The task: Backend for real-time communication app
  • 5. Elegant language & environment 1. Beautiful Language: Dynamic, OO, linear
  • 6. ## # Distribute a system message # def find_and_distribute(message_id) message = Message.find(message_id) raise SystemError, "Message not found" if message.nil? message.start_distribution return message.to_json rescue SystemError log.error "[API] distribute fail: "#{e.message}” end
  • 7. 1. Beautiful Language: Dynamic, OO, linear 2. Super ORM/ODM: ActiveRecord & Mongoid Elegant language & environment
  • 8. class MediaRobotUser include Mongoid::Document # schema field :rss_url, type: String field :updated, type: DateTime field :update_freq, type: Integer, default: 5 # Validations validates :rss_url, :presence => true validates :update_freq, :presence => true def activate_user robot_queue = ”robot_update_#{self.id.to_s}" Resque.remove_schedule(robot_queue) schedule_options = { 'every' => '15m', 'custom_job_class' => “Bot::Jobs::UpdateMediaRobot", 'queue' => :update_media_robot, 'args' => self.id.to_s, } Resque.set_schedule(robot_queue, schedule_options) end end # class MediaRobotUser
  • 9. 1. Beautiful Language: Dynamic, OO, linear 2. Super ORM/ODM: ActiveRecord & Mongoid 3. Robust libraries: Community focus on libs selected for Rails Elegant language & environment
  • 11. 1. Beautiful Language: Dynamic, OO, linear 2. Super ORM/ODM: ActiveRecord & Mongoid 3. Robust libraries: Rails gives focus on library development 4. Killer server stack for API: Thin + Rack + Sinatra Elegant language & environment
  • 12. Dedicated async web server for Ruby apps Instead of complex Apache/Passenger setup, you download thin and just run your app with it. Layer between web servers and web frameworks De facto standard in Ruby world: choose any ruby web server, choose any ruby framework, throw own middleware into soup and it just works! Simple HTTP request handler on top of Rack No MVC bloat for a simple, RESTful API application, but want still use same robust libraries Rails apps use. Just write functionality for your GET /my/api endpoint and go!
  • 13. # Set Rails session to OAuth2 access token convert middleware use Auth::RailsSessionConverter # Set OAuth2 handler use Rack::OAuth2::Server # launch Sinatra REST API server require File.dirname(__FILE__) + '/app/access/restapi' map('/rest/vp5/') { run Access::RESTAPI } 2. Define Rack configuration (e.g. myrack.ru): 3. Run web server: 1. Write Sinatra web app: ## # API call to get backend version. # get '/system/version' do authenticate!('int_api_user') content_type :json status 200 return (JSON :data_api_version => 'proto v5.0') end $ bundle exec thin –R myrack.ru –p 9400 -e development start Ruby ≠ Rails! Sinatra, Resque and many other cool frameworks Could map other apps to different paths “homemade” middleware block hooked in! No fuzz
  • 14. The next task: Backend for Media App
  • 15. 2013
  • 16. So.. Let’s think about Culture for unsecure code? Born in 2011 – are the libs there? Don’t want that callback spaghetti! DB drivers and ODMs?Performance ? How to keep running in production?
  • 17. /** * Static content delivery */ staticDelivery: function (req, res) { var tmpDir = lzconf.filedbdir + "/tmp"; file.mkdir(tmpDir, '777’, function() { var fileSource = lzconf.filedbdir + "/" + req.params[0]; // do the work easyimg.rescrop(options, function(err, image) { console.log('Resized and cropped: ', image); // send file res.sendfile(tmpTarget, {maxAge: 604800}, function(err) { if (err) { … } // remove temp file fs.unlink(tmpTarget, function(err, success) { … }); }); }); }); }
  • 18. function myApiFunc(callback) { /* * This pattern does NOT work! */ try { doSomeAsynchronousOperation(function (err) { if (err) throw (err); /* continue as normal */ }); } catch (ex) { callback(ex); } } Source: http://www.joyent.com/developers/node/design/errors Whaaat? Cannot use try…catch??
  • 19. “Sadly, that seems to be the story of Node.JS and the frameworks that use it. Derby, Meteor, SocketStream– they all are relatively new and immature, and in some cases, lack critical functionality of a web framework or have serious issues with security. That sort of puts me, as a developer, in an odd position. I’ve determined Node.JS is a good platform for a project, but without reinventing the wheel, what framework do I use to speed up development?” – Andrew Munsell https://www.andrewmunsell.com/blog/the-odd- state-of-nodejs-and-its-frameworks
  • 21. “Sinatra inspired web development framework for node.js – insanely fast, flexible, and simple.” Yes! Powered by Connect
  • 23. “Next generation web framework for node js.”
  • 24. Why it rocks ECMAScript 6: Generators $ node --harmony > function* giveMeFruit() { ... yield "apple"; ... yield "banana"; ... } > var fruitMachine = giveMeFruit() > fruitMachine.next() { value: 'apple', done: false } > fruitMachine.next() { value: 'banana', done: false } > fruitMachine.next() { value: undefined, done: true } > fruitMachine.next() Error: Generator has already finished at GeneratorFunctionPrototype.next (native) … What an earth this has to do with a HTTP framework?
  • 25. Why it rocks co– “The ultimate generator based flow- control goodness for nodejs (supports thunks, promises, etc)” var co = require('co'); co(function *(){ console.log(“updating user...”); try { var user = yield Users.findOneById(‘123’).exec(); if (!user) throw new Error(“Cannot find user”); user.name = “juha”; yield Promise.promisify(user.save, user)(); } catch (err) { console.log(“Name update failed: ”, err); } })() This Mongoose finder returns a promise by default “Save” need to be transferred into promise first for yield Try…catch as it should be 
  • 26. Generator flow control (co) is the heart of Koa server Why it rocks
  • 27. var koa = require('koa’) , api = require('./v1/myApiModule’), ... app.use(mount(‘/api/v1’, api)); app.listen(8080); Why it rocks Additional middleware to handle routing, e.g. koa- mount Custom middleware upstream & downstream app.use(function *(next) { var start = new Date; yield next; var ms = new Date - start; this.set('X-Response-Time', ms + 'ms'); }); Many needed middleware libs already ported, such as * koa-session-mongo * koa-passport * koa-cors * koa-send app.use(session()); app.use(passport.username()); app.use(function *(next) { try { yield next; } catch (err) { this.status = err.status || 500; } }) More robust code
  • 29. var Router = require('koa-router') var API = new Router() API.get('/topics/:topicId', function *() { try { this.body = yield MySubSystem.getTopic({ id: this.params.topicId, filter: this.request.query.filter_by }); } catch (err) { if (err.name === "DocumentNotFoundError") { this.body = "Topic not found"; this.status = 404; } else { throw err; } } } Why it rocks
  • 32. Where little posts make a mighty magazine. Where readers become editors. Where giving inspiration is rewarded. Thank you!

Editor's Notes

  • #2: From Ruby world to Node.js
  • #5: CMSs are not for realtime system Java felt more for enterprise level solution PHP language felt outdated and did not found suitable stack Rails MVC felt too heavy for API server purpose Pure Ruby with dedicated servers and framework was the choice
  • #17: Javascript famous for silently ignoring problems. Initially people did not handle CSRF. Sometimes neglected exception catching. Quickly written libs. No use of reverse proxy for caching and load balancing is needed.