Antonio Santiago
Software engineer as profession and hobby. A citizen of the world. Author of The Book of OpenLayers 3 and OpenLayers Cookbook.
Dynamic, object-oriented, prototype-oriented inheritance and general-purpose programming language
JavaScript runtime built on the Chome's V8 JavaScript engine (brings JavaScript to the server side).
Some words JavaScript programmers love to repeat...
...and the winner:
Don't block the event loop
# Python
import requests
r = requests.get('http://somewhere')
print r.text
print "I come after the request"
// JavaScript
var request = require('request');
request('http://somewhere', function (error, response, body) {
console.log(body);
})
console.log('I come after the request');
Synchronous
Asynchronous
Supposing task 3 depends on the response of task 2:
Synchronous
Asynchronous
JavaScript runtime built on the Chome's V8 JavaScript engine (brings JavaScript to the server side).
V8 compiles JavaScript source code directly into machine code when it is first executed.
There are no intermediate byte codes, no interpreter.
console.log('Node rocks !!!');
$ node ./app.js
Execute it:
./app.js
// Load the http module to create an http server.
var http = require('http');
// Listener to respond with Hello World to all requests.
function listener (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
}
// Create our HTTP server
var server = http.createServer(listener);
// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);
// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");
In day to day code you'll probably see:
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
});
var Service = {
someMethod: function() {
console.log('I made something');
};
};
module.exports = Service;
var Service = require('./Service');
Service.someMethod();
var Service2 = require('./Service');
Service2.someMethod();
./service.js
./app.js
Service === Service2
function Service() {
this.someMethod() {
console.log('I made something');
}
};
module.exports = new Service();
var Service = require('./Service');
Service.someMethod();
var Service2 = require('./Service');
Service2.someMethod();
./service.js
./app.js
Service === Service2
function Apple (type) {
this.type = type;
this.color = "red";
this.getInfo = function() {
return this.color + ' ' + this.type + ' apple';
};
}
module.exports = Apple;
var Apple1 = require('./apple');
var apple1 = new Apple1('monarch');
var Apple2 = require('./apple');
var apple2 = new Apple2('pink');
./apple.js
./app.js
Apple1 === Apple2
apple1 !== apple2
Instance of http.IncomingMessage
var method = request.method; // GET
var url = request.url; // /endpoint?param=value
var headers = request.headers;
// {
// 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*'
// }
var body = [];
request.on('error', function(err) {
console.error(err);
}).on('data', function(chunk) {
body.push(chunk);
}).on('end', function() {
body = Buffer.concat(body).toString();
});
console.log(body);
Instance of http.ServerResponse
response.statusCode = 200;
response.setHeader('Content-Type', 'application/json');
var responseBody = {
headers: headers,
method: method,
url: url,
body: body
};
response.write(JSON.stringify(responseBody));
response.end();
Respond with same data when accesing GET /echo
var http = require('http');
http.createServer(function(request, response) {
request.on('error', function(err) {
console.error(err);
response.statusCode = 400;
response.end();
});
response.on('error', function(err) {
console.error(err);
});
if (request.method === 'GET' && request.url === '/echo') {
request.pipe(response);
} else {
response.statusCode = 404;
response.end();
}
}).listen(8080);
First class networking and streaming but...
it can be a bit cumbersome working with core Node.js
Fast, unopinionated, minimalist web framework
var express = require('express')
var app = express()
app.get('/hello/:name', function (req, res) {
res.send('Hello ' + req.params.name)
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
A function that have access to the
Middlewares can:
function myBusiness(req, res, next) {
req.customData = {
token: 'sometoken',
data: 'somedatahere',
};
if (req.params.name === 'bye') {
res.status('200')
.send('Bye !!!');
}
next();
}
// Attach middleware to a path
app.get('/dosomething', myBusines);
var express = require('express')
var morgan = require('morgan')
var bodyParser = require('body-parser')
var cookieParser = require('cookie-parser')
var app = express()
app.use(morgan('combined')) // 127.0.0.1 - - [03/JUL/2015:16:54:25 +0000] "GET / HTTP/1.1" 200 13 "-" "MOZILLA/5.0 (MACINTOSH; INTEL MAC OS X 10_10_4) APPLEWEBKIT/600.7.12 (KHTML, LIKE GECKO) VERSION/8.0.7 SAFARI/600.7.12"
app.use(bodyParser.json()) // Parse request body content and stores in req.body object
app.use(cookieParser()) // Parse cookies and stores in req.cookies object
app.use(express.static('public')) // Serve static files from 'public' folder
var app = express()
var userRouter = app.route('/users')
userRouter.get('/:id(\\d+)', function(req, res, next) { ... });
userRouter.post('/:id(\\d+)', function(req, res, next) { ... });
userRouter.delete('/:id(\\d+)', function(req, res, next) { ... });
// Attach router to the app
app.use(userRouter);
Allow to create groups of actions...
Express request and response object has additional methods and properties than the request and response methods of the node callbacks
app.get('/something', doSomething);
const router = app.router('/users')
router.get('/products', doSomething)
app.use(router)
Similar to a normal middleware but has four parameters:
app.get('/dosomething', function(req, res, next) {
res.write('This is...');
next();
});
app.get('/dosomething', function(req, res, next) {
res.status(200).send('something !!!');
});
// Handle 404
app.use(function(req, res, next) {
res.status(404).end();
});
// Handle errors
app.use(function(err, req, res, next) {
res.status(500)
res.render('error', { error: err })
});
Express will catch errors and send to any middleware registered with four parameters.
app.use(function(req, res, next) {
// Runs always
});
app.all('/users', function(req, res, next) {
// Runs on all HTTP verbs
})
app.get('/users', function(req, res, next) {
// Runs for GET method
})
app.post('/users', function(req, res, next) {
// Runs for POST method
});
app.get('/users', middleware1, middleware2);
NOTE: Invoke next('route') to bypass remaining route callbacks
router.param('id', function (req, res, next, id) {
var user = ... // Retrive user from DB
req.user = user;
next();
});
router.get('/user/:id', function (req, res, next) {
var user = req.user;
// Do something with the user
...
});
By Antonio Santiago
High level description of Node and Express focusing on the main aspects.
Software engineer as profession and hobby. A citizen of the world. Author of The Book of OpenLayers 3 and OpenLayers Cookbook.