ANDRIY DACENKO
SOFTWARE ENGINEER
September 9, 2015
EXPRESS.JS - A NODE.JS WEB FRAMEWORK
BUILD API IN SECONDS
JS MENTORING 2015
WEB FRAMEWORK
Request
DATA
Handle
Get
Provide
Compile
Response
ITS ALL ABOUT
API
Request
Response
Render
express()
var express = require('express');
var app = express();
var root = 'public';
var options = {
index: 'main.html',
maxAge: '1d'
};
app.use(express.static(root, options));
app.use('/static', express.static('media'));
SETTINGS
var express = require('express');
var app = express();
app.get('env');
// => development
app.set('token', 'express');
app.get('token');
// => express
app.locals
app.locals.title = 'My App';
app.locals.fs = require('fs');
app.locals.email = 'me@myapp.com';
app.locals.title
// => 'My App'
app.locals.fs
// => {...}
app.locals.email
// => 'me@myapp.com'
Hello World!
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('Hello World!');
});
app.listen(3000);
app in app
var admin = express();
admin.get('/', function (req, res) {
console.log(admin.mountpath);
// => [ '/adm*n', '/manager' ]
res.send('Admin Homepage');
})
var secret = express();
secret.get('/', function (req, res) {
console.log(secret.mountpath);
// => /secr*t
res.send('Admin Secret');
});
admin.use('/secr*t', secret);
app.use(['/adm*n', '/manager'], admin);
ROUTING
app.get('/', function (req, res) {
res.send('GET request to homepage');
});
app.post('/', function (req, res) {
res.send('POST request to homepage');
});
app.put('/', function (req, res) {
res.send('PUT request to homepage');
});
app.delete('/', function (req, res) {
res.send('DELETE request to homepage');
});
METHOD
app.METHOD(path, callback [, callback ...])
|
|
|
ROUTE PATHS
path = 'hello';
path = 'hello*world';
path = /^hello\-world$/
// will match acd and abcd
'ab?cd'
// will match abcd, abbcd, abbbcd, and so on
'ab+cd'
// will match abcd, abxcd, abRABDOMcd, and so on
'ab*cd'
// will match abe and abcde
'ab(ce)?d'
ROUTE PARAMS
var express = require('express');
var app = express();
app.param('id', function (req, res, next, value) {
console.log('id = ', value);
next();
});
app.get('/user/:id', function (req, res, next) {
console.log('this matches');
next();
});
app.get('/user/:id/:page', function (req, res) {
console.log('and this matches too');
res.end();
});
app.listen(9090);
ROUTER
var app = express();
var products = express.Router();
products.route('/products')
.all(function(req, res, next) {
// pre validate request
})
.get(function(req, res, next) {
res.json(...);
})
.post(function(req, res, next) {
// add a new product...
});
app.use(products);
REQUEST
query
parameters
body
HTTP headers
REQ.APP
var express = require("express");
var app = express();
app.get("/views", function (req, res) {
console.log(req.app.get("views"));
});
BASE URL
var express = require("express");
var app = express();
var greet = express.Router();
greet.get('/jp', function (req, res) {
console.log(req.baseUrl); // /greet
res.send('Konichiwa!');
});
app.use('/greet', greet);
BODY
var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer');
// for parsing application/json
app.use(bodyParser.json());
// for parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: true
}));
// for parsing multipart/form-data
app.use(multer());
app.post('/', function (req, res) {
console.log(req.body);
res.json(req.body);
});
MISC
req.cookies.name
// => "john_doe"
// Host: "example.com:3000"
req.hostname
// => "example.com"
req.port
// => 3000
req.ip
// => "127.0.0.1"
// GET /user/john_doe
req.params.name
// => "john_doe"
// example.com/users?name=john_doe
req.path
// => "/users"
req.protocol
// => "https"
// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"
// GET /shoes?order=desc&shoe[color]=blue
req.query.order
// => "desc"
req.query.shoe.color
// => "blue"
// Host: "mobile.api.example.com"
req.subdomains
// => ["api", "mobile"]
req.xhr
// => true
ACCEPTS
app.get('/hello', function(req, res) {
switch(req.accepts(['json', 'html'])) {
case 'json':
res.setHeader('Content-Type', 'application/json')
res.write('{"hello":"world!"}')
break
case 'html':
res.setHeader('Content-Type', 'text/html')
res.write('<b>hello, world!</b>')
break
default:
// the fallback is text/plain
res.setHeader('Content-Type', 'text/plain')
res.write('hello, world!')
break
}
res.end();
});
RESPONSE
body
files
coockies
HTTP headers
PROPS
var express = require('express');
var app = express();
app.get('/views', function (req, res) {
console.log(res.app.get('views'));
res.locals.user = req.user;
res.locals.authenticated = !req.user.guest;
});
app.get('/', function (req, res) {
console.log(res.headersSent); // false
res.send('OK');
console.log(res.headersSent); // true
})
SEND
res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404)
.send('Sorry, we cannot find that!');
res.status(500).send({
error: 'something blew up'
});
SEND FILE
app.get('/user/:uid/photos/:file', function(req, res){
var uid = req.params.uid
, file = req.params.file;
req.user.mayViewFilesFrom(uid, function(yes){
if (yes) {
res.sendFile('/uploads/' + uid + '/' + file);
} else {
res.status(403).send('Sorry! you cant see that.');
}
});
});
DOWNLOAD
res.download('/img-123.pdf');
res.download('/img-123.pdf', 'img.png');
res.download('/img-123.pdf', 'img.png', function(err){
if (err) {
// Handle error, but response may be partially-sent
// so check res.headersSent
} else {
// decrement a download credit, etc.
}
});
JSON(P)
res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })
// ?callback=foo
res.jsonp({ user: 'john' })
// => foo({ "user": "john" })
app.set('jsonp callback name', 'cb');
// ?cb=foo
res.status(500).jsonp({ error: 'message' })
// => foo({ "error": "message" })
FORMAT
res.format({
text: function(){
res.send('hey');
},
html: function(){
res.send('<p>hey</p>');
},
json: function(){
res.send({ message: 'hey' });
}
});
COOKIES
res.cookie('name', 'john', { path: '/admin' });
res.clearCookie('name', { path: '/admin' });
res.cookie('name', 'john', { signed: true });
req.signedCookie('name');
// => john
res.cookie('name', 'john', {
domain: '.example.com',
path: '/admin',
secure: true
});
res.cookie('rememberme', '1', {
expires: new Date(Date.now() + 900000),
httpOnly: true
});
REDIRECT
res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');
res.redirect('back');
SET HEADERS
res.set('Content-Type', 'text/plain');
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
'ETag': '12345'
});
res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
res.append('Warning', '199 Miscellaneous warning');
HEADERS ALIASES
res.attachment();
// Content-Disposition: attachment
res.attachment('path/to/logo.png');
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png
res.links({
next: 'http://api.example.com/users?page=2',
last: 'http://api.example.com/users?page=5'
});
// Link <http://api.example.com/users?page=2>; rel="next",
// <http://api.example.com/users?page=5>; rel="last"
res.location('/foo/bar');
res.location('http://example.com');
res.location('back');
res.type('.html'); // => 'text/html'
res.type('html'); // => 'text/html'
res.type('json'); // => 'application/json'
res.type('application/json'); // => 'application/json'
res.type('png'); // => 'image/png'
res.sendStatus(200); // res.status(200).send('OK')
res.sendStatus(403); // res.status(403).send('Forbidden')
res.sendStatus(404); // res.status(404).send('Not Found')
res.sendStatus(500); // res.status(500).send('Internal Server Error')
res.sendStatus(2000); // res.status(2000).send('2000')
RENDERING
var app = express();
app.set('views', './views');
app.set('view engine', 'jade');
app.get('/', function (req, res) {
res.render('index', {
title: 'Hey',
message: 'Hello there!'
});
});
// index.jade
html
head
title!= title
body
h1!= message
npm i jade --save
ENGINE
var fs = require('fs');
app.engine('rpl', function (filePath, options, callback) {
fs.readFile(filePath, function (err, content) {
if (err) return callback(new Error(err));
var rendered = content.toString()
.replace('%title%', '<title>'+ options.title +'</title>')
.replace('%message%', '<h1>'+ options.message +'</h1>');
return callback(null, rendered);
})
});
app.set('views', './views');
app.set('view engine', 'rpl');
app.get('/', function (req, res) {
res.render('index', {
title: 'Hey',
message: 'Hello there!'
});
})
MIDDLEWARE
App
Router
Error
Third-party
APP LEVEL
var app = express();
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
ROUTER LEVEL
var app = express();
var router = express.Router();
router.get('/user/:id', function (req, res, next) {
// if user id is 0, skip to the next router
if (req.params.id == 0) next('route');
// else pass the control to the next middleware in this stack
else next(); //
}, function (req, res, next) {
// render a regular page
res.render('regular');
});
// handler for /user/:id which renders a special page
router.get('/user/:id', function (req, res, next) {
console.log(req.params.id);
res.render('special');
});
app.use('/', router);
ERRORS
app.use(function(err, req, res, next) {
console.error(err.stack);
if (req.app.enabled('debug')) {
res.status(500).send(err);
} else {
next();
}
});
app.use(function(err, req, res, next) {
res.status(500).send('Something broke!');
});
LINKS
Project - https://github.com/strongloop/express
Docs - http://expressjs.com
Generator - https://github.com/expressjs/generator
Middleware - http://expressjs.com/resources/middleware.html
Q&A Time
ANDRIY DACENKO
SOFTWARE ENGINEER
September 9, 2015
EXPRESS.JS - A NODE.JS WEB FRAMEWORK
BUILD API IN SECONDS
Express.js - a node.js web framework
By Andrew Dacenko
Express.js - a node.js web framework
Server programming using Node.js Express.js – a node.js web framework
- 1,316