NodeJS
John Machahuay Giraldo
About me
- Full Stack developer at Belatrix.
- Originally a Web developer, now doing both web and mobile development
- Now building an app for IOS and android with React Native
- Speaker in meetups.
Agenda
- Why, When and What's Node.js?
- Checking our Javascript
- Node.js Hello World
- What's and how to use NPM
- Dependencies with Common.js
- Callbacks, callbacks and more callbacks
- Express.js to the rescue
- Mongoose and MongoDB
- Going real time with Socket.io
Why Node.js
Why, When and What's Node.js
Why Node.js
Why, When and What's Node.js
Why Node.js
Why, When and What's Node.js
Why Node.js
Why, When and What's Node.js
Companies using Node.js
Why Node.js
Why, When and What's Node.js
Why Node.js
Why, When and What's Node.js
Why, When and What's Node.js
Why Node.js
Callback
Blocking I/O
Why Node.js
Why, When and What's Node.js
When Node.js
Why, When and What's Node.js
NODE.JS SYSTEM ARCHITECTURE
What's Node.js
Why, When and What's Node.js
What's Node.js
Why, When and What's Node.js
Node.js is a runtime that uses the same V8 Javascript engine you can find in the Google Chrome browser. But that wouldn't be enough for Node.js's success - Node.js utilizes libuv, a multi-platform support library with a focus on asynchronous I/O.
From a developer's point of view Node.js is single-threaded - but under the hood libuv handles threading, file system events, implements the event loop, features thread pooling and so on. In most cases you won't interact with it directly.
What's Node.js: A Hello Node App
Why, When and What's Node.js
// See node-lessons/lesson_0/index.js
var http = require('http');
var PORT = process.env.PORT || 8080;
var HOSTNAME = process.env.HOSTNAME || 'localhost';
var NODE_ENV = process.env.NODE_ENV || 'development';
var counter=0;
var server = http.createServer(function(request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<!DOCTYPE "html">');
response.write('<html>');
response.write('<head>');
response.write('<title>Hello Node Page</title>');
response.write('</head>');
response.write('<body>');
response.write('Hello Node.js ' + counter + ' running as ' + NODE_ENV + '!');
response.write('</body>');
response.write('</html>');
response.end();
console.log('counter: ' + counter + ' request url: ' + request.url);
counter++;
});
server.listen(PORT, HOSTNAME);
console.log('Server is listening at PORT:' + PORT);
What are Node.js modules
Why, When and What's Node.js
- 1 to 1 correspondence with 1 file
- Modules are loaded synchronously
- Modules are cached
-
Core modules come with the platform
-
ex: require('http')
-
-
3rd party modules are published as packages to a registry (such as NPM)
-
use:npm install
- installed into node_modules directory
-
-
File modules
- require path starts with '/', './', or '../'
How require(...) works?
Why, When and What's Node.js
If not a core module, and not an explicit path (whether absolute or relative):
- Looks in module's directory for node_modules/
- if not found, continue searching each parent directory until file system root ( / )
- Throw an error (code: MODULE_NOT_FOUND)
How require(...) works?
Why, When and What's Node.js
When requiring a path instead of an explicit file
- Look for package.json ("main" property)
- Look for index.js
EX: require('./my_awesome_lib')
Folder as module
// example content of ./my_awesome_lib/package.json
{ "name" : "my-awesome-library",
"main" : "./implementation/my_lib_impl.js" }
How require(...) works?
Why, When and What's Node.js
Modules can be installed globally using:
- npm install -g [module_name]
But that's just recommended for Command Line Interface (CLI) modules
EX: npm install -g express-generator
Global modules
How require(...) works?
Why, When and What's Node.js
More details at:
What's NPM
NPM is the package manager used by Node.js applications - you can find a ton of modules here, so you don't have to reinvent the wheel. It is like Maven for Java or Composer for PHP. There are two primary interfaces you will interact with - the NPM website and the NPM command line toolkit.
Installing NPM packages globally
npm install <package-name> -g
Using NPM
# It shows up current NPM installed version
npm --version
# Initialize current folder creating
# a package.json file to store dependencies
npm init
# Shows up NPM configuration like used
# folders
npm config list
# List every globally installed module
npm list --g[lobal]
# List every locally installed module
npm list
# Locally installs express and also adds it
# to package.json
npm install express --save
# Locally installs specific modules but
#just for dev environments
npm install mocha chai --save-dev
# Installs all dependencies declared at
# package.json even dev dependencies
npm install
# Just installs non development
# specific dependencies.
npm install --production
# Locally uninstall a module
npm uninstall express
# Installs a particular module version
npm install underscore@1.8.2
# Updates a module but following what's
# configured at package.json
npm update underscore
More about NPM
THE SIMPLEST MODULE
Dependencies with Common.js
// See node-lessons/lesson_1/hello.js
console.log('Hello World');
// See node-lessons/lesson_1/app.js
require('./hello.js');
>node app.js
Hello World
>
PATTERN 1: DEFINE A GLOBAL
Dependencies with Common.js
// See node-lessons/lesson_2/foo.js
foo = function () {
console.log('foo!');
}
// See node-lessons/lesson_2/foo.js
require('./foo.js');
foo();
>node app.js
foo!
>
PATTERN 2: EXPORT AN ANONYMOUS FUNCTION
Dependencies with Common.js
// See node-lessons/lesson_3/bar.js
module.exports = function () {
console.log('bar!');
}
// See node-lessons/lesson_3/app.js
var bar = require('./bar.js');
bar();
>node app.js
bar!
>
PATTERN 3: EXPORT A NAMED FUNCTION
Dependencies with Common.js
// See node-lessons/lesson_4/fiz.js
exports.fiz = function () {
console.log('fiz!');
}
// See node-lessons/lesson_4/app.js
var fiz = require('./fiz.js').fiz;
fiz();
>node app.js
fiz!
>
PATTERN 4: EXPORT AN ANONYMOUS OBJECT
Dependencies with Common.js
// See node-lessons/lesson_5/buz.js
var Buz = function () {};
Buz.prototype.log = function () {
console.log('buz!');
};
module.exports = new Buz();
// See node-lessons/lesson_5/app.js
var buz = require('./buz.js');
buz.log();
>node app.js
buz!
>
PATTERN 5: EXPORT A NAMED OBJECT
Dependencies with Common.js
// node-lessons/lesson_6/baz.js
var Baz = function () {};
Baz.prototype.log = function () {
console.log('baz!');
};
exports.Baz = new Baz();
// node-lessons/lesson_6/app.js
var baz = require('./baz.js').Baz;
baz.log();
>node app.js
baz!
>
Callback Hell / Bumeran Code /
Callbacks, callbacks and more callbacks
Callbacks Hell / Bumeran Code
Callbacks, callbacks and more callbacks
// Improving code readability
function x (a) {
do_something(function(){
process(a);
});
}
// can be converted to this:
function x (a) {
do_something(y_maker(a)); // notice we're calling y_maker,
// not passing it in as callback
}
function y_maker (b) {
return function () {
process(b);
};
}
Callbacks
Callbacks, callbacks and more callbacks
Async.js to the rescue
Callbacks, callbacks and more callbacks
Async provides around 70 functions that include the usual 'functional' suspects:
- map
- reduce
- filter
- each
- parallel
- series
- waterfall
As well as some common patterns for asynchronous control flow:
Async.js : series
Callbacks, callbacks and more callbacks
// See node-lessons/lesson_9/async_series.js
var async = require('async');
async.series([
function(callback){
console.log('1st function call starts.');
setTimeout(function(){
console.log('1st function call resolved.');
callback(null, 1); // err, result
}, 1000);
},
function(callback){
console.log('2nd function call starts.');
setTimeout(function(){
console.log('2nd function call resolved.');
callback(null, 2, 3); // err, results
}, 100);
}
],
function(err, results){
// err propagates all errors within the series functions
// results holds all the results, [1, [2, 3]] in this case
console.log('Results return in order as expected ;)');
console.dir(results);
});
Async.js : parallel
Callbacks, callbacks and more callbacks
// See node-lessons/lesson_9/async_parallel.js
var async = require('async');
async.parallel([
function(callback){
console.log('1st function call starts.');
setTimeout(function(){
console.log('1st function call resolved.');
callback(null, 1); // err, result
}, 1000);
},
function(callback){
console.log('2nd function call starts.');
setTimeout(function(){
console.log('2nd function call resolved.');
callback(null, 2); // err, result
}, 100);
}
],
function(err, results){
// err propagates all errors within the parallel functions
// results holds all the results, [1, 2] in this case
console.log('But results return in order as expected ;)');
console.dir(results);
});
Async.js : waterfall
Callbacks, callbacks and more callbacks
// See node-lessons/lesson_9/async_waterfall.js
var async = require('async');
var WINK = ';)';
var SMILEY = ':D';
var TONGUE = ':P';
async.waterfall([
function(callback){
console.log('1st function call starts.');
setTimeout(function(){
console.log('1st function call resolved.');
callback(null, WINK, SMILEY); // err, result, ... cascade params
}, 5000);
},
function(arg1, arg2, callback){
console.log(['2nd function call starts receiving arg1:',
arg1,
'and arg2:',
arg2,
'.'].join(' '));
setTimeout(function(){
console.log('2nd function call resolved.');
var prefix = 'result ';
callback(null,
prefix + TONGUE,
prefix + arg2,
prefix + arg1); // err, ... multiple results is ok
}, 3000);
}
],
function(err, result1, result2, result3){
// err propagates all errors within the waterfall functions
console.log('Important: waterfall can handle multiple results.');
console.dir(result1);
console.dir(result2);
console.dir(result3);
});
More about Async.js?
Callbacks, callbacks and more callbacks
Express.js to the rescue
Express.js to the rescue
# Installing Express in our project
npm install express --save
# Do you need a middleware for handling JSON, Raw, Text and URL encoded form data?
npm install body-parser --save
# Do you need a middleware to parse cookies from request headers and populate
# req.cookies with an object keyed by the cookie names?
npm install cookie-parser --save
# Do you need a middleware for handling multipart/form-data?
npm install multer --save
# Do you need session handling using cookie store?
npm install cookie-session --save
# Do you need server logs?
npm install morgan --save
# Do you need to serve static content (i.e. html pages, images, css)?
npm install serve-static --save
# Do you need an authentication library?
npm install passport --save
# Do you want CLI assistance to create your App?
# then globally install express and express-generator
npm install -g express express-generator
Preflight check on
Express.js to the rescue
//server.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
First flight on Express.js
Express.js to the rescue
What is Middleware
Middleware pattern is a series of processing units connected together, where the output of one unit is the input for the next one. In Node.js, this often means a series of functions in the form:
function(request, response, next) {
// ... Run some code
next();
};
request -> middleware1 -> middleware2 -> ...middlewareN -> route -> app -> response
Tipical Flow:
Express.js to the rescue
Applying Express middleware
var express = require('express');
var app = express();
//... Define middleware1-N
app.use(middleware1);
app.use(middleware2);
...
app.use(middlewareN);
Express.js to the rescue
Middleware order
var express = require('express');
var logger = require('morgan');
var bodyParser = require('body-parser');
var app = express();
...
app.use(logger('dev'));
app.use(bodyParser.json());
Middlewares are executed in the specified order:
Express.js to the rescue
Two Categories of Express Middleware
- npm modules, e.g., body-parser
- Custom Middleware
Express.js to the rescue
Custom Middleware
Creating a Custom Middleware using a reference
Creating a Custom Middleware with anonymous function definition
...
var middleware = function (request, response, next) {
// Modify request or response
// Execute the callback when done
next();
};
...
app.use(middleware);
app.use(function (request, response, next) {
// Modify request or response
// Execute the callback when done
next();
});
Express.js to the rescue
Template Engines
Some examples
Express.js to the rescue
Template Engines
Express.js uses by default
PUG ???... really? ... well ... yes
JADE
Express.js to the rescue
Template Engines: JADE
Collection
Document
MongoDB query
Typical SQL query
MongoDB query with projection control
MongoDB insert
MongoDB update
MongoDB remove
MongoDB aggregated query
MongoDB documents relationship
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a schema
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date
});
// the schema is useless so far
// we need to create a model using it
var User = mongoose.model('User', userSchema);
// make this available to our users in our Node applications
module.exports = User;
Mongoose
// if our user.js file is at app/models/user.js
var User = require('./app/models/user');
// create a new user called chris
var chris = new User({
name: 'Chris',
username: 'sevilayha',
password: 'password'
});
// call the built-in save method to save to the database
chris.save(function(err) {
if (err) throw err;
console.log('User saved successfully!');
});
Mongoose
Socket.io main objective
Socket.io main objective is to enable real time applications on any browser
- Socket between Server & Client
- Send data between clients
- Receive event based data
- Supports almost any browser
- Supports Multiple sockets on a single connection
- Detects disconnection using heartbits
- 100% javascript
- Available on NPM
Socket.io typical usage
Socket.io is real time
Socket.io fallback methods
Socket.io handshake
client socket.io
Node.js server + socket.io
Socket.io handshake
client socket.io
Node.js server + socket.io
transport getway, id and config are returned
Basic server setup
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket){
socket.emit('helloworld', { hello: 'world' });
socket.on('other event', function (data) {
console.log(data);
});
});
Basic client setup
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('other event', { the: 'data' });
});
</script>
?
Thanks
Copy of Node.js FUNdamentals
By johnprog
Copy of Node.js FUNdamentals
- 1,820