var express = require("express"),
app = express();
app.get("/", function(req, res) {
res.send("Hello World");
});
app.use(function(req, res) {
res.sendStatus(404);
});
var server = app.listen(3000, function() {
var port = server.address().port;
console.log("Express server listening on port %s", port);
});
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);
A middleware:
- Can modify the
req
andres
objects; - Passes control to next middleware by calling
next
; - Can end the request-response cycle;
- Order matters, in the example above:
myLogger
is executed before the root route;
Route matching:
- In
app.use
, thepath
is a prefix, default to/
, so a route like/foo
will match any paths like/foo/bar
,/foo/bar/blah
, so/
matches every request; - But in
app.METHOD
, thepath
matches the whole path, so a route like/foo
will match only/foo
or/foo/
;
You can use app.route
to attach multiple HTTP verb handlers to a route, avoiding duplicate route names:
var app = express()
app.route('/events')
.all(function (req, res, next) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
})
.get(function (req, res, next) {
res.json({})
})
.post(function (req, res, next) {
// maybe add a new event...
})
/* GET */
app.get("/:name", function(req, res, next) {
var name = req.parmas.name; // get the name parameter
var queries = req.queries; // all GET queries
// ...
});
/* POST */
app.use(express.bodyParser()); // add a middleware, it makes req.body available
app.post("/", function(req, res, next) {
var postData = req.body; // get all the post data
// ...
});
Use app.param
to add a call back for request parameters:
app.param('id', function (req, res, next, id) {
console.log('CALLED ONLY ONCE')
next()
})
app.get('/user/:id', function (req, res, next) {
console.log('although this matches')
next()
})
app.get('/user/:id', function (req, res) {
console.log('and this matches too')
res.end()
})
On GET /user/42
, the following is printed:
CALLED ONLY ONCE
although this matches
and this matches too
- The param callback is called only once, even multiple routes has the same parameter;
- It is called before the route handler;
-
Serve static content for the app from the
public
directory in the application directory, the request path doesn't need to be prefixed with/public
:// GET /style.css etc app.use(express.static(path.join(__dirname, 'public')))
-
Mount the middleware at
/static
to serve static content only when their request path is prefixed with/static
:// GET /static/style.css etc. app.use('/static', express.static(path.join(__dirname, 'public')))
-
Disable logging for static content requests by loading the logger middleware after the static middleware:
app.use(express.static(path.join(__dirname, 'public'))) app.use(logger())
-
Serve static files from multiple directories, but give precedence to
./public
over the others:app.use(express.static(path.join(__dirname, 'public'))) app.use(express.static(path.join(__dirname, 'uploads')))
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
})
- Express has a default error handler at the end of middleware stack, it outputs the call stack in non-production envs;
- You can add a custom error handler, which must have four parameters, it should either end the response or call
next()
to pass, otherwise the request will hang;
You can have a separate express app to handle only a paticular route, in this example, we have an admin
app handling the /admin
route.
var express = require('express')
var app = express() // the main app
var admin = express() // the sub app
admin.get('/', function (req, res) {
console.log(admin.mountpath) // /admin
res.send('Admin Homepage')
})
app.use('/admin', admin) // mount the sub app
A router
object is an isolated instance of middleware and routes, it's like a "mini-application";
- Every express app has a built-in app router;
- You can create a new router by
express.Router()
; - And it can be used just as a middleware by an app or another router:
app.use(router)
,router.use(anotherRouter)
; - In practice: you can use a router for a particular root URL, in this way separating your routes into files or even mini-apps;
const router = express.Router();
// invoked for any requests passed to this router
router.use(function (req, res, next) {
// .. some logic here .. like any other middleware
next()
})
// `/calendar/events` matches this route
router.get('/events', function (req, res, next) {
// ..
})
// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', router)
const express = require('express');
const https = require('https');
const http = require('http');
const app = express();
const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
This works because the app
returned by express()
is in fact a callback function, app.listen()
is a convenient method for:
app.listen = function () {
const server = http.createServer(this)
return server.listen.apply(server, arguments)
}
In localhost, you can create your own CA, generate your own SSL cert, see: https://stackoverflow.com/a/60516812