NodeJS #3
Utilisé par Disney, PayPal, Walmart, Mozilla, Yahoo, Macy's, ...
Utilisé par Myspace, Klout, GeekList, Ghost, Apiary, ...
Auteur initial: TJ Holowaychuk
Auteurs : même team qu'Express
Utilisé par GoDaddy, Symantec, BankOfAmerica, ...
npm install express --save
Infrastructure Web minimaliste,
souple et rapide pour Node.js
Réalisation d'applications Web & API
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
sudo npm install express-generator -g
Installation du paquet en global
express monprojet
Ensuite
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.post('/', function (req, res) {
res.send('Got a POST request');
});
app.put('/user', function (req, res) {
res.send('Got a PUT request at /user');
});
app.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user');
});
GET
POST
DELETE
PUT
app.all('/secret', function (req, res, next) {
console.log('Accessing the secret section ...');
next(); // pass control to the next handler
});
Dans tous les cas (all)
app.get('/ab?cd', function(req, res) {
res.send('ab?cd');
});
abcd ou acd
app.get('/ab+cd', function(req, res) {
res.send('ab+cd');
});
abcd ou abbcd ou abbbcd ou ...
app.get('/ab*cd', function(req, res) {
res.send('ab*cd');
});
abcd ou abfoocd ou abbarcd ou ...
var cb0 = function (req, res, next) {
console.log('CB0');
next();
}
var cb1 = function (req, res, next) {
console.log('CB1');
next();
}
var cb2 = function (req, res) {
res.send('Hello from C!');
}
app.get('/example/c', [cb0, cb1, cb2]);
var express = require('express');
var router = express.Router();
router.get('/about', function(req, res) {
res.send('About birds');
});
module.exports = router;
var birds = require('./birds');
...
app.use('/birds', birds);
app.js
birds.js
app.get('/user/:id', function(req, res) {
res.send('user ' + req.params.id);
});
Passer des params (req.params)
// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"
Query
req.xhr
// => true
Requête AJAX ?
res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
Redirection
// pass a local variable to the view
res.render('user', { name: 'Tobi' }, function(err, html) {
// ...
});
Rendre une vue
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' });
Retourner une réponse http
res.json(null);
res.json({ user: 'tobi' });
res.status(500).json({ error: 'message' });
Retourner une réponse JSON
res.download('/r.pdf', 'report.pdf', function(err){
if (err) {
// Handle error, but keep in mind the response
// may be partially-sent
// so check res.headersSent
} else {
// decrement a download credit, etc.
}
});
Télécharger un fichier
Les fonctions middleware effectuent les tâches suivantes :
Pour passer au middleware suivant, il faut utiliser la méthode "next" :
next();
var express = require('express');
var app = express();
var myLogger = function (req, res, next) {
console.log('LOGGED');
next();
};
app.use(myLogger);
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000);
L'ordre de déclaration des middlewares est important !
var app = express();
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
Possibilité de le brancher sur un point de montage
var express = require('express');
var router = express.Router();
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
// load the cookie-parsing middleware
app.use(cookieParser());
Parse Cookie header and populate req.cookies with an object keyed by the cookie names
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
4 arguments au lieu de 3 !
app.use(express.static(path.join(__dirname, 'public')));
var options = {
dotfiles: 'ignore',
etag: false,
extensions: ['htm', 'html'],
index: false,
maxAge: '1d',
redirect: false,
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now());
}
}
app.use(express.static('public', options));
Configurable
npm install --save-dev jade
En CLI :
Dans app.js
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
Dans les routes
app.get('/', function (req, res) {
res.render('index', { title: 'Hey' });
});
Autres moteurs de rendu possibles
EJS,
Handlebars,
Hogan
JADE par défaut
Class Literal
a.button
.content
ID Literal
a#button
#button
<a class="button"></a>
<div class="content"></div>
<a id="button"></a>
<div id="content"></div>
a(class={active: currentUrl === '/'} href='/') Home
Class attributes
- var classes = ['foo', 'bar', 'baz']
a(class=classes)
Attributes
a.button(href='google.com') Google
<a href="google.com" class="button">Google</a>
input(
type='checkbox'
name='agreement'
checked
)
<input type="checkbox" name="agreement" checked="checked"/>
Unbuffered code
- list = ["Uno", "Dos", "Tres"]
each item in list
li= item
Buffered code
p= 'This code is' + ' <escaped>!'
p!= 'This code is' + ' <strong>not</strong> escaped!'
<p>This code is <strong>not</strong> escaped!</p>
<p>This code is <escaped>!</p>
- var friends = 10
case friends
when 0
p you have no friends
when 1
p you have a friend
default
p you have #{friends} friends
Case
- var user = { description: 'foo bar baz' }
- var authorised = false
#user
if user.description
h2 Description
p.description= user.description
else if authorised
h2 Description
p.description.
User has no description,
why not add one...
else
h1 Description
p.description User has no description
Conditions
//- layout.jade
doctype html
html
head
block title
title Default title
body
block content
Extends
//- index.jade
extends ./layout.jade
block title
title Article Title
block content
h1 My Article
+
//- index.jade
doctype html
html
include ./head.jade
body
h1 My Site
p Welcome
include ./foot.jade
Includes
//- foot.jade
#footer
p Copyright (c) foobar
+
En cas de doute : http://html2jade.org
exercice
- var items = { '/': 'Home', '/users': 'Users', '/settings': 'Settings' };
// 1) itérer sur l'object pour afficher le markup d'un menu
// * Les clés correspondent au href des liens,
// * Les valeurs correspondent aux textes des liens
// --> Le menu doit être une liste <ul> de liens <li>
// 2) Attribuer une classe "odd" aux liens dont l'index est pair
// Attribuer une classe "even" aux liens dont l'index est impair
exercice
Générer une application express à l'aide du générateur.
En utilisant la session, gérer une liste d'utilisateurs (affichage de la liste, ajout dans la liste et suppression)