SlideShare a Scribd company logo
Koajs as an alternative to Express
I am Mykola Kozhuharenko
front-end dev in Krusche & Company
I’m on github
Hello!
Nodejs/Express downsides:
◉Code readability
Callback hell
◉Error handling
Duplicate callbacks / cb call might be lost in third
party library
If you miss an error handler - you are in troubles
Can't throw an error or use try/catch
app.post('/',function (req, res, next) {
var body = req.body;
if (!body.name || !body.email || !body.password) {
return res.status(400).send("Missing username or email or password")
};
// case #1- if user was registered (socials platform) before -> just add a password;
User.findOneAndUpdate({
email: body.email
}, {
$set: {password: body.password}
}, (err, user) => {
if (!user) {
// case #2 - user has never been registering before -> create new one;
User.create(body, (err, user) => {
if (err && err.name === 'ValidationError') {
return res.status(400).send(err)
} else if (err) {
return res.status(500).send(err)
}
return res.send({ user: user })
});
} else {
return res.send({ user: body })
}
});
});
Callbacks
User.findOneAndUpdate({
email: body.email
}, {
$set: {password: body.password}
}, (err, user) => {
if (err) {
return res.status(500).send(err)
}
if (!user) {
// case #2 - user has never been registering before -> create new one;
User.create(body, (err, user) => {
if (err && err.name === 'ValidationError') {
return res.status(400).send(err)
} else if (err) {
return res.status(500).send(err)
}
return res.send({ user: user })
});
} else {
return res.send({ user: body })
}
});
Callbacks
◉ If you miss an error handler -
you are in troubles
◉ Duplicate callbacks / cb call
might be lost in third party
library
// foo is a function that returns a generator
function *foo() {
console.log('start');
yield 1;
console.log('second');
yield 2;
yield 3;
}
var gen = foo(); // get a generator object
gen.next() // 'start', { value: 1, done:false }
gen.next() // 'second', { value: 2, done:false }
gen.next() // { value: 3, done:false }
gen.next() // { value: undefined, done:true }
Generators #1
const Message = require('./models/message');
function *foo() {
yield new Promise((resolve, reject) => {
resolve("Hello")
});
yield Message.create({text: 'some text');
}
var gen = foo();
var genVal = gen.next().value // { value: Promise, done:false }
genVal.then(res => console.log(res)) // Hello
gen.next() // { value: Promise, done:false }
Generators #2 - Promises
const Message = require('./models/message');
function *foo() {
var greeting = yield new Promise.resolve('Hello');
var result = yield Message.create({text: greeting});
console.log(result) // saved! {id: 'ID', text: 'Hello'}
}
var gen = foo();
gen.next().value // Promise
.then(greeting => {
console.log(greeting); // 'Hello'
gen.next(greeting).value // Promise
.then(createRes = gen.next(createRes))
})
Generators #3 - Two ways
var fetch = require('isomorphic-fetch');
function *foo() {
try {
var greeting = yield fetch('/api/get-greetings')[0];
} catch (e) {
console.log(e);
}
}
var gen = foo();
gen.next().value
.then(greeting => gen.next(greeting))
.catch(e => gen.throw(e))
Generators #4 - throw
function runner (gen) {
var gen = gen();
next(null, null);
function next(err, res) {
const res = err ? gen.throw(err) : gen.next(res);
if (res.done) return;
res.value
.then((res) => next(null, res))
.catch((error) => next(error));
}
};
runner(function *foo() {
var greeting = yield Promise.resolve("Hello")
var name = yield Promise.resolve("John")
console.log(greeting, name); // 'Hello John'
})
Generators #5 - Runner
var co = require('co')
app.post('/',function (req, res, next) {
var body = req.body;
co(function *() {
try {
var user = yield User.findOneAndUpdate({
email: body.email
}, { $set: {password: body.password} });
if (!user) {
user = yield User.create(body);
}
res.send({ user: user })
} catch (e) {
if (err && err.name === 'ValidationError') {
return res.status(400).send(err)
} else if (err) {
return res.status(500).send(err)
}
}
});
});
Co
Using Co you can yield:
Thunks
(will be deprecated)
Arrays
co(function* () {
// parallel
var res = yield [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
];
console.log(res); // => [1, 2, 3]
}).catch(onerror);
Generators
function* greet() {
return yield new Promise((resolve, rej) => {
resolve("Hello, Mary!")
});
}
co(function *(){
var greeting = yield greet
console.log(greeting)
}).catch((err) => {
console.log(err)
});
Promises
Co
Along with co will be useful:
◉mz - promisify NodeJS core modules
◉Thenify promisify any callback-based function
var fs = require('mz/fs')
fs.exists(__filename).then(function (exists) {
if (exists) // do something
})
var thenify = require('thenify');
var somethingAsync = thenify(function somethingAsync(a, b, c, callback) {
callback(null, a, b, c);
});
Adopted by community
Callbacks Async Promises Generators
(along with co)
Meet Koa!
Philosophically, Koa aims to "fix and replace node",
whereas Express "augments node"
Koa Hello world
var koa = require('koa');
var app = koa();
app.use(function *() {
this.body = 'Hello World';
});
app.listen(3000);
Koa API
koa Request
CONTEXT
this.request
this.response
koa Response
this.query
this.url
this.headers
this.get - get a header
this.body
this.type - get content-type
this.redirect
this.status
this.set -set a header
app.use(function *(next) {
var start = new Date; // <<<------ 1
yield next; // waits for downstream middlewares
var delta = Math.ceil(Date.now() - start); // <<<------ 3
console.info(`${this.method} ${this.url} - ${delta}ms`);
this.set('X-Response-Time', delta + 'ms'); // <<<------ 4
});
app.use(function *() {
this.body = yield new Promise.resolve([10000]); // <<<------ 2
});
Response time - Koa middleware
3
4
2
1
Custom error
app.use(function *(next) {
try {
yield next;
} catch (e) {
if (e instanceof AuthError) {
this.statusCode = e.status;
this.redirect('/not-authorized');
this.body = this.render('not-authorized');
} else if (e.status) {
this.statusCode = e.status;
this.body = this.render('error', e);
} else {
this.statusCode = 500;
this.body = this.render('error', e);
logger.error('Unexpected error: ', e); // winston
}
}
});
app.use(function *(next) {
throw new AuthError()
});
app.post('/',function (req, res, next) {
var body = req.body;
if (!body.name || !body.email || !body.password) {
return res.status(400).send("Missing username or email or password")
};
// case #1- if user was registered (socials platform) before -> just add a password;
User.findOneAndUpdate({
email: body.email
}, { $set: {password: body.password} }, (err, user) => {
if (err) return res.status(500).send(err)
if (!user) {
// case #2 - user has never been registering before -> create new one;
User.create(body, (err, user) => {
if (err && err.name === 'ValidationError') {
return res.status(400).send(err)
} else if (err) {
return res.status(500).send(err)
}
return res.send({ user: user })
});
} else {
return res.send({ user: body })
}
});
});
Do you remember this example with callbacks?
app.use(function *(next) {
try {
yield next;
} catch (e) {
if (e.status) { // app error
this.body = e.message;
this.statusCode = e.status;
} if else (e && e.name ===
'ValidationError') {
this.body = e;
this.statusCode = 400;
} else { // Internal server error
this.body = "Oops!";
this.status = 500;
}
}
});
Koa way
app.use(function *(next) {
var body = this.request.body;
if (!body.name || !body.email || !body.password) {
throw new Error("Missing username||email||password");
}
var user = yield User.findOneAndUpdate({email: body.email}, {
$set: {password: body.password}
});
if (!user) user = yield User.create(body);
this.body = { user: this.body };
});
2nd middleware
1st middleware
app.get('/', function (req, res, next) {
var readStream = fs.createReadStream('text.txt');
readStream.pipe(res);
readStream.on('error', () => {
res.statusCode = 500;
res.end('Server error has occurred!');
});
res.on('close', () => readStream.destroy());
});
Send a file
app.use(function* (next) {
this.body = fs.createReadStream('text.txt')
});
Express/node
Koa
“
“Koa and express uses the same modules.
We’ve refactored express into jshttp and
pillarjs so that anyone else can make their
own framework as well”
Express & Koa similarities
Same modules
Accepts, content-type,
cookie, fresh, content-
disposition, on-finished,
parseurl, type-is, vary,
escape-html
Modular
Each feature is moved to a
separate module.
Minimalistic
Contains only essential
(core) modules (e.g.
headers parsing).
Same developers
Koa was build by core
developers of Express:
TJ Holowaychuk and
others
Koa middlewares:
◉koa-router
◉koa-bodyparse
◉koa-static
◉koa-session
◉koa-compress
◉koa-cors
◉Koa-logger
more here
Koa
◉ router
◉ bigger community
◉ needs domains to catch async
errors
◉ close to node style
◉ a lot of outdated examples and
tutorials
Express
vs
◉ better error handling with try catch
◉ nice async flow control (no cb hell)
◉ api is more stable;
◉ no build-in router
◉ smaller community
◉ support stream out of the box
◉ easy to understand source code; no
monkey patching
Any questions ?
Thanks!

More Related Content

What's hot

Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
andrewnacin
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
Kirill Chebunin
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Kacper Gunia
 
Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendKirill Chebunin
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
Marcello Duarte
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
Marcello Duarte
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio Martín
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
Kacper Gunia
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Puppet modules for Fun and Profit
Puppet modules for Fun and ProfitPuppet modules for Fun and Profit
Puppet modules for Fun and Profit
Alessandro Franceschi
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the newRemy Sharp
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creationbenalman
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
Konstantin Kudryashov
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
Luca Mearelli
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 

What's hot (20)

Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK MeetupScaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
 
Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friend
 
Coffee Script
Coffee ScriptCoffee Script
Coffee Script
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Puppet modules for Fun and Profit
Puppet modules for Fun and ProfitPuppet modules for Fun and Profit
Puppet modules for Fun and Profit
 
jQuery: out with the old, in with the new
jQuery: out with the old, in with the newjQuery: out with the old, in with the new
jQuery: out with the old, in with the new
 
jQuery Plugin Creation
jQuery Plugin CreationjQuery Plugin Creation
jQuery Plugin Creation
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
A Little Backbone For Your App
A Little Backbone For Your AppA Little Backbone For Your App
A Little Backbone For Your App
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 

Similar to Koajs as an alternative to Express - OdessaJs'16

node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascriptEldar Djafarov
 
Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
Felix Geisendörfer
 
2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript
Johannes Hoppe
 
2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript
Johannes Hoppe
 
Ember.js for a CakePHP Developer
Ember.js for a CakePHP DeveloperEmber.js for a CakePHP Developer
Ember.js for a CakePHP Developer
jtrapp07
 
JSLab. Домников Виталий. "ES6 генераторы и Koa.js"
JSLab. Домников Виталий. "ES6 генераторы и Koa.js"JSLab. Домников Виталий. "ES6 генераторы и Koa.js"
JSLab. Домников Виталий. "ES6 генераторы и Koa.js"
GeeksLab Odessa
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
Mariano Iglesias
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
Sebastiano Armeli
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by expressShawn Meng
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
Santosh Wadghule
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
Stoyan Stefanov
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Seri Moth
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bitsChris Saylor
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
Bradley Holt
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
Peter Friese
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5arajivmordani
 
All you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsAll you need to know about JavaScript Functions
All you need to know about JavaScript Functions
Oluwaleke Fakorede
 
Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015
Lukas Ruebbelke
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
Visual Engineering
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
Michael Girouard
 

Similar to Koajs as an alternative to Express - OdessaJs'16 (20)

node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
 
2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript2013-06-15 - Software Craftsmanship mit JavaScript
2013-06-15 - Software Craftsmanship mit JavaScript
 
2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript2013-06-24 - Software Craftsmanship with JavaScript
2013-06-24 - Software Craftsmanship with JavaScript
 
Ember.js for a CakePHP Developer
Ember.js for a CakePHP DeveloperEmber.js for a CakePHP Developer
Ember.js for a CakePHP Developer
 
JSLab. Домников Виталий. "ES6 генераторы и Koa.js"
JSLab. Домников Виталий. "ES6 генераторы и Koa.js"JSLab. Домников Виталий. "ES6 генераторы и Koa.js"
JSLab. Домников Виталий. "ES6 генераторы и Koa.js"
 
Going crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHPGoing crazy with Node.JS and CakePHP
Going crazy with Node.JS and CakePHP
 
EcmaScript 6 - The future is here
EcmaScript 6 - The future is hereEcmaScript 6 - The future is here
EcmaScript 6 - The future is here
 
Build web application by express
Build web application by expressBuild web application by express
Build web application by express
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02Jsphp 110312161301-phpapp02
Jsphp 110312161301-phpapp02
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
All you need to know about JavaScript Functions
All you need to know about JavaScript FunctionsAll you need to know about JavaScript Functions
All you need to know about JavaScript Functions
 
Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015
 
Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6Workshop 10: ECMAScript 6
Workshop 10: ECMAScript 6
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 

Recently uploaded

Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Sanjeev Rampal
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
Arif0071
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
JeyaPerumal1
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
Rogerio Filho
 
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Brad Spiegel Macon GA
 
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
keoku
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
3ipehhoa
 
Internet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptxInternet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptx
VivekSinghShekhawat2
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
Gal Baras
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
laozhuseo02
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
natyesu
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
3ipehhoa
 
Comptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guideComptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guide
GTProductions1
 
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
ufdana
 
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdfJAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
Javier Lasa
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
laozhuseo02
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
3ipehhoa
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
nirahealhty
 
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
eutxy
 
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC
 

Recently uploaded (20)

Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
 
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
 
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
 
Internet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptxInternet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptx
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
 
Comptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guideComptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guide
 
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
 
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdfJAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
 
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
 
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
 

Koajs as an alternative to Express - OdessaJs'16

  • 1. Koajs as an alternative to Express
  • 2. I am Mykola Kozhuharenko front-end dev in Krusche & Company I’m on github Hello!
  • 3. Nodejs/Express downsides: ◉Code readability Callback hell ◉Error handling Duplicate callbacks / cb call might be lost in third party library If you miss an error handler - you are in troubles Can't throw an error or use try/catch
  • 4. app.post('/',function (req, res, next) { var body = req.body; if (!body.name || !body.email || !body.password) { return res.status(400).send("Missing username or email or password") }; // case #1- if user was registered (socials platform) before -> just add a password; User.findOneAndUpdate({ email: body.email }, { $set: {password: body.password} }, (err, user) => { if (!user) { // case #2 - user has never been registering before -> create new one; User.create(body, (err, user) => { if (err && err.name === 'ValidationError') { return res.status(400).send(err) } else if (err) { return res.status(500).send(err) } return res.send({ user: user }) }); } else { return res.send({ user: body }) } }); }); Callbacks
  • 5. User.findOneAndUpdate({ email: body.email }, { $set: {password: body.password} }, (err, user) => { if (err) { return res.status(500).send(err) } if (!user) { // case #2 - user has never been registering before -> create new one; User.create(body, (err, user) => { if (err && err.name === 'ValidationError') { return res.status(400).send(err) } else if (err) { return res.status(500).send(err) } return res.send({ user: user }) }); } else { return res.send({ user: body }) } }); Callbacks
  • 6. ◉ If you miss an error handler - you are in troubles ◉ Duplicate callbacks / cb call might be lost in third party library
  • 7. // foo is a function that returns a generator function *foo() { console.log('start'); yield 1; console.log('second'); yield 2; yield 3; } var gen = foo(); // get a generator object gen.next() // 'start', { value: 1, done:false } gen.next() // 'second', { value: 2, done:false } gen.next() // { value: 3, done:false } gen.next() // { value: undefined, done:true } Generators #1
  • 8. const Message = require('./models/message'); function *foo() { yield new Promise((resolve, reject) => { resolve("Hello") }); yield Message.create({text: 'some text'); } var gen = foo(); var genVal = gen.next().value // { value: Promise, done:false } genVal.then(res => console.log(res)) // Hello gen.next() // { value: Promise, done:false } Generators #2 - Promises
  • 9. const Message = require('./models/message'); function *foo() { var greeting = yield new Promise.resolve('Hello'); var result = yield Message.create({text: greeting}); console.log(result) // saved! {id: 'ID', text: 'Hello'} } var gen = foo(); gen.next().value // Promise .then(greeting => { console.log(greeting); // 'Hello' gen.next(greeting).value // Promise .then(createRes = gen.next(createRes)) }) Generators #3 - Two ways
  • 10. var fetch = require('isomorphic-fetch'); function *foo() { try { var greeting = yield fetch('/api/get-greetings')[0]; } catch (e) { console.log(e); } } var gen = foo(); gen.next().value .then(greeting => gen.next(greeting)) .catch(e => gen.throw(e)) Generators #4 - throw
  • 11. function runner (gen) { var gen = gen(); next(null, null); function next(err, res) { const res = err ? gen.throw(err) : gen.next(res); if (res.done) return; res.value .then((res) => next(null, res)) .catch((error) => next(error)); } }; runner(function *foo() { var greeting = yield Promise.resolve("Hello") var name = yield Promise.resolve("John") console.log(greeting, name); // 'Hello John' }) Generators #5 - Runner
  • 12. var co = require('co') app.post('/',function (req, res, next) { var body = req.body; co(function *() { try { var user = yield User.findOneAndUpdate({ email: body.email }, { $set: {password: body.password} }); if (!user) { user = yield User.create(body); } res.send({ user: user }) } catch (e) { if (err && err.name === 'ValidationError') { return res.status(400).send(err) } else if (err) { return res.status(500).send(err) } } }); }); Co
  • 13. Using Co you can yield: Thunks (will be deprecated) Arrays co(function* () { // parallel var res = yield [ Promise.resolve(1), Promise.resolve(2), Promise.resolve(3), ]; console.log(res); // => [1, 2, 3] }).catch(onerror); Generators function* greet() { return yield new Promise((resolve, rej) => { resolve("Hello, Mary!") }); } co(function *(){ var greeting = yield greet console.log(greeting) }).catch((err) => { console.log(err) }); Promises
  • 14. Co
  • 15. Along with co will be useful: ◉mz - promisify NodeJS core modules ◉Thenify promisify any callback-based function var fs = require('mz/fs') fs.exists(__filename).then(function (exists) { if (exists) // do something }) var thenify = require('thenify'); var somethingAsync = thenify(function somethingAsync(a, b, c, callback) { callback(null, a, b, c); });
  • 16. Adopted by community Callbacks Async Promises Generators (along with co)
  • 17. Meet Koa! Philosophically, Koa aims to "fix and replace node", whereas Express "augments node"
  • 18. Koa Hello world var koa = require('koa'); var app = koa(); app.use(function *() { this.body = 'Hello World'; }); app.listen(3000);
  • 19. Koa API koa Request CONTEXT this.request this.response koa Response this.query this.url this.headers this.get - get a header this.body this.type - get content-type this.redirect this.status this.set -set a header
  • 20. app.use(function *(next) { var start = new Date; // <<<------ 1 yield next; // waits for downstream middlewares var delta = Math.ceil(Date.now() - start); // <<<------ 3 console.info(`${this.method} ${this.url} - ${delta}ms`); this.set('X-Response-Time', delta + 'ms'); // <<<------ 4 }); app.use(function *() { this.body = yield new Promise.resolve([10000]); // <<<------ 2 }); Response time - Koa middleware 3 4 2 1
  • 21. Custom error app.use(function *(next) { try { yield next; } catch (e) { if (e instanceof AuthError) { this.statusCode = e.status; this.redirect('/not-authorized'); this.body = this.render('not-authorized'); } else if (e.status) { this.statusCode = e.status; this.body = this.render('error', e); } else { this.statusCode = 500; this.body = this.render('error', e); logger.error('Unexpected error: ', e); // winston } } }); app.use(function *(next) { throw new AuthError() });
  • 22. app.post('/',function (req, res, next) { var body = req.body; if (!body.name || !body.email || !body.password) { return res.status(400).send("Missing username or email or password") }; // case #1- if user was registered (socials platform) before -> just add a password; User.findOneAndUpdate({ email: body.email }, { $set: {password: body.password} }, (err, user) => { if (err) return res.status(500).send(err) if (!user) { // case #2 - user has never been registering before -> create new one; User.create(body, (err, user) => { if (err && err.name === 'ValidationError') { return res.status(400).send(err) } else if (err) { return res.status(500).send(err) } return res.send({ user: user }) }); } else { return res.send({ user: body }) } }); }); Do you remember this example with callbacks?
  • 23. app.use(function *(next) { try { yield next; } catch (e) { if (e.status) { // app error this.body = e.message; this.statusCode = e.status; } if else (e && e.name === 'ValidationError') { this.body = e; this.statusCode = 400; } else { // Internal server error this.body = "Oops!"; this.status = 500; } } }); Koa way app.use(function *(next) { var body = this.request.body; if (!body.name || !body.email || !body.password) { throw new Error("Missing username||email||password"); } var user = yield User.findOneAndUpdate({email: body.email}, { $set: {password: body.password} }); if (!user) user = yield User.create(body); this.body = { user: this.body }; }); 2nd middleware 1st middleware
  • 24.
  • 25. app.get('/', function (req, res, next) { var readStream = fs.createReadStream('text.txt'); readStream.pipe(res); readStream.on('error', () => { res.statusCode = 500; res.end('Server error has occurred!'); }); res.on('close', () => readStream.destroy()); }); Send a file app.use(function* (next) { this.body = fs.createReadStream('text.txt') }); Express/node Koa
  • 26. “ “Koa and express uses the same modules. We’ve refactored express into jshttp and pillarjs so that anyone else can make their own framework as well”
  • 27.
  • 28. Express & Koa similarities Same modules Accepts, content-type, cookie, fresh, content- disposition, on-finished, parseurl, type-is, vary, escape-html Modular Each feature is moved to a separate module. Minimalistic Contains only essential (core) modules (e.g. headers parsing). Same developers Koa was build by core developers of Express: TJ Holowaychuk and others
  • 30. Koa ◉ router ◉ bigger community ◉ needs domains to catch async errors ◉ close to node style ◉ a lot of outdated examples and tutorials Express vs ◉ better error handling with try catch ◉ nice async flow control (no cb hell) ◉ api is more stable; ◉ no build-in router ◉ smaller community ◉ support stream out of the box ◉ easy to understand source code; no monkey patching