SlideShare a Scribd company logo
1 of 15
Web Archiving and Analytics by Qumram:
Lessons Learnt
Leonid Kyrpychenko
Qumram
@distributedLeo and @qumramAG
Barcelona
May 19th 2015
2
3
What are the lessons
learnt so far with Q5?
4
5
Lesson 1. Mocking is a MUST
stateManager = {
frameSent: function () {}
};
network = proxyquire('./network', {
'./stateManager': stateManager
});
With AngularJS we use standard ngMock.
We use jasmine in front and backend (but not only).
For the browser applications we use Proxyquireify (requires browserify)
6
Lesson 2. DOM changes not always
update innerHtml
// Risky Tag Names that should be handled manually
var tags = ['input', 'textarea', 'select', 'option'],
// Risky Attributes to backup
attributes = ['value', 'selected', 'checked', 'disabled'],
// Risky Attributes that has no value
noValueAttributes = ['selected', 'checked', 'disabled'];
7
Lesson 3. Compression and diffing
without web workers
/**
* Queue a work to the end of the javascript runtime excecution queue
*/
queueWork: function(context, fnNameOrReference, params, callback){
// add context to top of params, so that apply passes params correctly to bind
params.unshift(context);
// bind callback to context and add callback to end of parameter list
params.push(callback.bind(context));
// we use apply on bind because the params in array, bind needs each params as argument,
wheres
// apply can take a paramter array, so we do apply on bind.
if (typeof fnNameOrReference == 'string') {
setTimeout(Function.bind.apply(context[fnNameOrReference],params),0);
} else {
setTimeout(Function.bind.apply(fnNameOrReference,params),0);
}
},
8
Lesson 4. Track events with different
speed
To throttle the rate a function gets executed we use debouncing
var interval = config.get('recordMouseMovement').duration;
setInterval((function (buffer, activeMouseCordinates, lastRecordedMouseCordinates)
{
return recordMousePosition;
})(buffer, activeMouseCordinates, lastRecordedMouseCordinates), interval)
self.api.deBouncedFilter = debounce(self.api.filter, 400);
9
Lesson 5. Parse html in a new iFrame was
a huge bottleneck
var domParser = new DOMParser();
domParser.parseFromString(html, 'text/html');
10
Lesson 6. Browserify
return gulp.src(['./components/tracker/index.js'])
.pipe(transform(function(filename) {
return browserify({
entries: filename,
debug: true
}).bundle();
}))
.pipe(transform(function() {
return exorcist('./build/qumram.tracker.js.map');
}))
.pipe(rename('qumram.tracker.js'))
…
11
Lesson 7. Promises and bluebird
'use strict';
var bluebird = require('bluebird');
var mongodb = require('mongodb');
var config = require('./config.js');
bluebird.promisifyAll(mongodb);
bluebird.promisifyAll(mongodb.MongoClient);
bluebird.promisifyAll(mongodb.MongoClient.prototype);
bluebird.promisifyAll(mongodb.Collection);
bluebird.promisifyAll(mongodb.Collection.prototype);
bluebird.promisifyAll(mongodb.Cursor.prototype);
module.exports = {
/**
* initialise database connection
*/
init: function () {
return mongodb.MongoClient.connectAsync(config.dburl)
.then(function (db) {
module.exports.client = db;
});
}
};
12
Lesson 8. Koa
var koa = require('koa');
var cors = require('koa-cors');
var socket = require('koa-socket');
var qmrmRouter = require('qmrm-router');
var http = require('http');
var app = koa();
app.use(cors());
app.use(qmrmRouter.middleware());
socket.use(function *(next) {
this.method = this.event.split(' ')[0].toUpperCase();
this.path = this.event.split(' ')[1];
yield next;
this.socket.emit('resp ' + this.event, this.body);
});
socket.use(qmrmRouter.middleware());
socket.start(app);
app.server = [];
app.server[0] = http.createServer(app.callback());
app.init();
app.server[0].listen(3000);
13
Lesson 9. Sockets + REST router =
QRouter
npm install qrouter
var QmrmRouter = require('qrouter');
var router = new QmrmRouter();
router.options('/tokens', cors());
router.post('post_tokens', 'ack.post_tokens', '/tokens', cors(), function
(req, res) {
var token = req.body;
github.com/qumram/qrouter
14
Join US!
Jobs@Qumram.com
15

More Related Content

Similar to 20150519 qumram barcelona_js

Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
OSCON - ES6 metaprogramming unleashed
OSCON -  ES6 metaprogramming unleashedOSCON -  ES6 metaprogramming unleashed
OSCON - ES6 metaprogramming unleashedJavier Arias Losada
 
Building resilient applications
Building resilient applicationsBuilding resilient applications
Building resilient applicationsNuno Caneco
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsSimo Ahava
 
Java Concurrency and Asynchronous
Java Concurrency and AsynchronousJava Concurrency and Asynchronous
Java Concurrency and AsynchronousLifan Yang
 
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at RuntimeOSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at RuntimeNETWAYS
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Wilson Su
 
Efficient Memory and Thread Management in Highly Parallel Java Applications
Efficient Memory and Thread Management in Highly Parallel Java ApplicationsEfficient Memory and Thread Management in Highly Parallel Java Applications
Efficient Memory and Thread Management in Highly Parallel Java ApplicationsPhillip Koza
 
DBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse EngineeringDBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse EngineeringSahil Dhar
 
NodeJs
NodeJsNodeJs
NodeJsdizabl
 
Java script performance tips
Java script performance tipsJava script performance tips
Java script performance tipsShakti Shrestha
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limitsDroidcon Berlin
 
Angular Intermediate
Angular IntermediateAngular Intermediate
Angular IntermediateLinkMe Srl
 

Similar to 20150519 qumram barcelona_js (20)

Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
OSCON - ES6 metaprogramming unleashed
OSCON -  ES6 metaprogramming unleashedOSCON -  ES6 metaprogramming unleashed
OSCON - ES6 metaprogramming unleashed
 
Building resilient applications
Building resilient applicationsBuilding resilient applications
Building resilient applications
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
 
Java Concurrency and Asynchronous
Java Concurrency and AsynchronousJava Concurrency and Asynchronous
Java Concurrency and Asynchronous
 
ES6 metaprogramming unleashed
ES6 metaprogramming unleashedES6 metaprogramming unleashed
ES6 metaprogramming unleashed
 
Junit_.pptx
Junit_.pptxJunit_.pptx
Junit_.pptx
 
Use me strict
Use me strictUse me strict
Use me strict
 
6976.ppt
6976.ppt6976.ppt
6976.ppt
 
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at RuntimeOSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
OSMC 2021 | inspectIT Ocelot: Dynamic OpenTelemetry Instrumentation at Runtime
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8
 
Efficient Memory and Thread Management in Highly Parallel Java Applications
Efficient Memory and Thread Management in Highly Parallel Java ApplicationsEfficient Memory and Thread Management in Highly Parallel Java Applications
Efficient Memory and Thread Management in Highly Parallel Java Applications
 
DBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse EngineeringDBI-Assisted Android Application Reverse Engineering
DBI-Assisted Android Application Reverse Engineering
 
NodeJs
NodeJsNodeJs
NodeJs
 
What`s new in Java 7
What`s new in Java 7What`s new in Java 7
What`s new in Java 7
 
Java script performance tips
Java script performance tipsJava script performance tips
Java script performance tips
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
JavaScript Basics
JavaScript BasicsJavaScript Basics
JavaScript Basics
 
Android programming -_pushing_the_limits
Android programming -_pushing_the_limitsAndroid programming -_pushing_the_limits
Android programming -_pushing_the_limits
 
Angular Intermediate
Angular IntermediateAngular Intermediate
Angular Intermediate
 

Recently uploaded

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
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
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 

Recently uploaded (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
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
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 

20150519 qumram barcelona_js

  • 1. Web Archiving and Analytics by Qumram: Lessons Learnt Leonid Kyrpychenko Qumram @distributedLeo and @qumramAG Barcelona May 19th 2015
  • 2. 2
  • 3. 3
  • 4. What are the lessons learnt so far with Q5? 4
  • 5. 5 Lesson 1. Mocking is a MUST stateManager = { frameSent: function () {} }; network = proxyquire('./network', { './stateManager': stateManager }); With AngularJS we use standard ngMock. We use jasmine in front and backend (but not only). For the browser applications we use Proxyquireify (requires browserify)
  • 6. 6 Lesson 2. DOM changes not always update innerHtml // Risky Tag Names that should be handled manually var tags = ['input', 'textarea', 'select', 'option'], // Risky Attributes to backup attributes = ['value', 'selected', 'checked', 'disabled'], // Risky Attributes that has no value noValueAttributes = ['selected', 'checked', 'disabled'];
  • 7. 7 Lesson 3. Compression and diffing without web workers /** * Queue a work to the end of the javascript runtime excecution queue */ queueWork: function(context, fnNameOrReference, params, callback){ // add context to top of params, so that apply passes params correctly to bind params.unshift(context); // bind callback to context and add callback to end of parameter list params.push(callback.bind(context)); // we use apply on bind because the params in array, bind needs each params as argument, wheres // apply can take a paramter array, so we do apply on bind. if (typeof fnNameOrReference == 'string') { setTimeout(Function.bind.apply(context[fnNameOrReference],params),0); } else { setTimeout(Function.bind.apply(fnNameOrReference,params),0); } },
  • 8. 8 Lesson 4. Track events with different speed To throttle the rate a function gets executed we use debouncing var interval = config.get('recordMouseMovement').duration; setInterval((function (buffer, activeMouseCordinates, lastRecordedMouseCordinates) { return recordMousePosition; })(buffer, activeMouseCordinates, lastRecordedMouseCordinates), interval) self.api.deBouncedFilter = debounce(self.api.filter, 400);
  • 9. 9 Lesson 5. Parse html in a new iFrame was a huge bottleneck var domParser = new DOMParser(); domParser.parseFromString(html, 'text/html');
  • 10. 10 Lesson 6. Browserify return gulp.src(['./components/tracker/index.js']) .pipe(transform(function(filename) { return browserify({ entries: filename, debug: true }).bundle(); })) .pipe(transform(function() { return exorcist('./build/qumram.tracker.js.map'); })) .pipe(rename('qumram.tracker.js')) …
  • 11. 11 Lesson 7. Promises and bluebird 'use strict'; var bluebird = require('bluebird'); var mongodb = require('mongodb'); var config = require('./config.js'); bluebird.promisifyAll(mongodb); bluebird.promisifyAll(mongodb.MongoClient); bluebird.promisifyAll(mongodb.MongoClient.prototype); bluebird.promisifyAll(mongodb.Collection); bluebird.promisifyAll(mongodb.Collection.prototype); bluebird.promisifyAll(mongodb.Cursor.prototype); module.exports = { /** * initialise database connection */ init: function () { return mongodb.MongoClient.connectAsync(config.dburl) .then(function (db) { module.exports.client = db; }); } };
  • 12. 12 Lesson 8. Koa var koa = require('koa'); var cors = require('koa-cors'); var socket = require('koa-socket'); var qmrmRouter = require('qmrm-router'); var http = require('http'); var app = koa(); app.use(cors()); app.use(qmrmRouter.middleware()); socket.use(function *(next) { this.method = this.event.split(' ')[0].toUpperCase(); this.path = this.event.split(' ')[1]; yield next; this.socket.emit('resp ' + this.event, this.body); }); socket.use(qmrmRouter.middleware()); socket.start(app); app.server = []; app.server[0] = http.createServer(app.callback()); app.init(); app.server[0].listen(3000);
  • 13. 13 Lesson 9. Sockets + REST router = QRouter npm install qrouter var QmrmRouter = require('qrouter'); var router = new QmrmRouter(); router.options('/tokens', cors()); router.post('post_tokens', 'ack.post_tokens', '/tokens', cors(), function (req, res) { var token = req.body; github.com/qumram/qrouter
  • 15. 15

Editor's Notes

  1. Part of our architecture
  2. Can be shown in qumramapi/app/mongodb.js, (node-service-template branch) we are using bluebird to promisify mongodb native library. Qumramui/gulp_tasks can be shown to show how we leverage promises for better structured readable code.