Modern server side development with node.js - Benjamin gruenbaum

Preview:

Citation preview

Modern Server Side Development with

NodeJSWhat changed since the 0.10 days

Benjamin Gruenbaum

Benjamin Gruenbaum• I work @ TipRanks• NodeJS core collaborator.• Promises guy, bluebird fan and core contributor.• I argue with people online.• StackOverflow guy.

This talk is in 3 partsThe Past

The PresentThe Future

Let’s go back to 2009

JavaScript on the Server

JavaScript on the server is an old idea

Netscape Enterprise Server – 1995Steve Yegge’s Server – 2008

JavaScript on the server is a good idea?

Remember, 2008- JavaScript engines are painfully slow.APIs were nonexistent.Language was hated.

Suddenly – V8Google needed fast JavaScript in Chrome –

so JavaScript engines became fast.

This Ryan guy thought… let’s make a non-blocking server.

As in – no thread “block”s in the user server code.

What can we write this in?

We need a language that doesn’t have file/net APIs yet to get a sane ecosystem.

JavaScript has no blocking APIs

The Result – solving “The 10K

Problem”

How: The Event LoopThreads and OS non-blocking APIs push things into queues

User code runs on a single thread and executes handlers on the queues

Why even write node?It’s fast enough.

Why even write node?Server and client in one language

Why even write node?It was cool

Remember: in 2009 JS is all the hotness

Code Sample: Chat Servernet.createServer(function(socket) { var user = users.add(socket) socket.on('data', function(data) { <- Callback user.sendOthers("> " + data) });  socket.on('close', function(hadError) { <- Callback user.leave(); });}).listen(8000);

Ryan joined Joyent, which looked over

Node

Initially, things worked well – Node got traction

But… Stagnation started.

No new ES features, even when available in Chrome.

Fast Forward to last year

NodeJS was forked into Io.js

Goal: Modern V8

Goal: Modern APIs

Goal: Inclusivity

Goal: Adopt modern JS

Eventually, io.js won. The projects merged.

The result of the io.js fork:Modern V8 version.

NodeJS on top of the io.js fork rather than the Joyent repo.

Handing over of the Joyent repo to the NodeJS foundation.

Community governance. Lots of new features for the community.

Just how different is Node today?

Current version: Node 7+Node 0.12 – last yearfunction persistCriticalFile(cb) { fs.readFile("criticalFile", function(err, data) { if(err) return cb(err); db.persist("collection", process(data), function(err, result) { if(err) return cb(err); cb(null, result); }); });}

Current version: Node 7+Node 7 – this year

async function persistCriticalFile(cb) { const data = await fs.readFileAsync("criticalFile"); return await db.persistAsync("collection", process(data));}

So – how do we develop with Node 7?Let’s look at a simple scenario. You want to get the comments to a post on your site.

- First, from the cache if they’re there. - If they’re not, from the database.

So – how do we develop with Node 7?

Node 0.x:app.get('/getComments/:userId', function(req, res){ var userId = req.params.userId; commentCache.get(userId, function(err, data) { if(err) {  instrumentation.log(err);  return res.json(err); } if(data) return res.json(data); db.getCommentsByUserId(userId, function(err, data) {  if(err) {    instrumentation.log(err);    return res.status(500).end(err);  }  cache.store(data, function() {});  return res.json(data);   }); });

});

So – how do we develop with Node 7?

Node 0.x:app.get('/getComments/:userId', function(req, res){

var userId = req.params.userId;  commentCache.get(userId, function(err, data) { if(err) {  instrumentation.log(err);  return res.json(err); } if(data) return res.json(data); db.getCommentsByUserId(userId, function(err, data) {  if(err) {     instrumentation.log(err);     return res.status(500).end(err);  }  cache.store(data, function() {});  return res.json(data);    });

  });});

So – how do we develop with Node 7?

Node 0.x:app.get('/getComments/:userId', function(req, res){ var userId = req.params.userId;  commentCache.get(userId, function(err, data) {

if(err) {  instrumentation.log(err);  return res.json(err); } if(data) return res.json(data); db.getCommentsByUserId(userId, function(err, data) {  if(err) {     instrumentation.log(err);     return res.status(500).end(err);  }  cache.store(data, function() {});  return res.json(data);    });  });});

So – how do we develop with Node 7?

Node 0.x:app.get('/getComments/:userId', function(req, res){ var userId = req.params.userId;  commentCache.get(userId, function(err, data) { if(err) {  instrumentation.log(err);  return res.json(err); }

if(data) return res.json(data); db.getCommentsByUserId(userId, function(err, data) {  if(err) {     instrumentation.log(err);     return res.status(500).end(err);  }  cache.store(data, function() {});  return res.json(data);    });  });});

So – how do we develop with Node 7?

Node 0.x:

db.getCommentsByUserId(userId, function(err, data) {  if(err) {     instrumentation.log(err);     return res.status(500).end(err);  }  cache.store(data, function() {});  return res.json(data);    });  });

So – how do we develop with Node 7?

app.get('/getComments/:userId', ({params: {userId}}, res) => { const fromCache = await commentCache.get(userId); if(fromCache) return res.json(fromCache); const fromDb = await db.getCommentsByUserId(userId); res.json(fromDb); commentCache.store(userId, fromDb);}); 

How our flow has changed: tests

Old

it("does something", function(done) { myApi("someData", function(err, result) { assert.equal(err, null); assert.equal(result === 3); done(); });});

New

it("does something", async () => { assert.equal(await myApi("someData", 3)); });

How our flow has changed: classes

Old

function User(id) { this.id = id; } User.prototype.foo = function(id){ doBar(id); }

New

class User { constructor(id) { this.id = id } foo() { doBar(id); } }

How our development flow changed.• Hot reload servers in JS• Node first approaches in client side flows• The rise of universal JS

How our web flow changed.• Rest vs. GraphQL/Falcor.• Native debugger.• Handling request/response cycles.• How express changed.• How clustering changed.

How production changed.• The rise of containers.• More people into node.• Community got a lot bigger, a lot more mature.• Node backed by major companies.• Node for IoT, node on Chakra.

What’s coming next?

Async Iteratorsasync function* map(fn) { // async + generator, great stream processing for await(const value of this) yield fn(value); };

Observables

Core API Promises

node –expose-wasm

ES Modulesimport {some, other} from "module name"

libuv.jsLower level NodeJS

Code?

Just a few words about open source

You don’t have to be an expertWe’ll onboard you

Node is actively looking…

benjamingr@gmail.com

Questions?The Past

The PresentThe Future

Thank You