- Define middleware.
- Parse POST and PUT/PATCH requests with the
body-parser
. - Handle logs and error messages with
morgan
anderrorhandler
.
As you build a number of different applications in Express, you'll find that there are a few pieces of Express middleware that you'll be reaching for over and over again - they're found in almost every project.
Middleware | Package Name | Purpose | Installed by Generator? |
---|---|---|---|
Serve-Static | N/A - now bundled in Express | Serve up static pages. | ✅ |
CORS | cors |
Create a CORS policy for the app. | 🚫 |
BodyParser | body-parser |
Easily read the body of an incoming request. | ✅ |
Morgan | morgan |
Logging. | ✅ |
ErrorHandler | errorhandler |
Self-explanatory. | 🚫 |
Remember how, when we were building applications in Rails, we would have a public
folder for holding static HTML and other assets? Well, serve-static allows us to do the same thing in Express. Just hook it up to your app and pass it a folder name to use it.
app.use(express.static('public'));
Now any static asset (HTML, CSS, JS, images) you put inside public
will be served up automatically.
In your teams, create a new small Express app that serves up one of the following three static images (or any other three images that you'd prefer to serve):
If you deploy your API to heroku, but deploy your front-end to GitHub, pay attention!
Fortunately, dealing with CORS is Express is pretty easy - just download the CORS middleware via NPM, and then require and use it inside app.js
.
npm install --save cors
// app.js
var cors = require('cors');
//...
app.use(cors());
This will give us a blanket white-list CORS policy, which isn't so great for real life, but is fine for now.
Reading the body of an incoming request is mission-critical for just about every possible web application. body-parser
gives us an easy interface for reading that request body, so that we don't have to worry about (a) loading data chunks one at a time, or (b) making sure that the body is in the right format.
// app.js
var bodyParser = require('body-parser');
// ...
app.use(bodyParser.json());
This will add an additional property, .body
to the request object that your middleware interacts with, which you can then immediately use to grab data.
router.post('/', function(req, res) { // create
models.Person.create(req.body).then(function(person){
res.json(person);
}, function(err){
console.error(err);
});
// res.send("people#create");
});
Back when we were working with Rails, you may or may not have noticed a directory inside your projects called log
; this is where your Rails app would keep an ongoing record of everything it's ever done. This can be an extremely useful tool for debugging, and is really a core feature for just about any web application.
// create a write stream (in append mode)
var accessLogStream = fs.createWriteStream('logs/access.log', {flags: 'a'});
// setup the logger
app.use(morgan('combined', {stream: accessLogStream}));
Create a new directory called logs
in the root of your project. If you skip this, you will get an error!
errorhandler
, as the name implies, is a piece of middleware that's designed to help manage how errors are handled. Unlike the other middleware mentioned so far, errorhandler
is for use in development only; this is because errorhandler
sends its full stack trace back to the client anytime there's an error, and that is not something you want to happen in production.
npm install --save-dev errorhandler # notice the flag!
// app.js
var errorhandler = require('errorhandler');
// ...
if (process.env.NODE_ENV === 'development') {
// only use in development
app.use(errorhandler())
}
One other thing to be aware of with Express that 404 errors are not handled by default, so you'll need to create a catch-all route to handle them. An example of this is below:
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
// Error handler is `use`d next, so 'next' refers to it. This line calls that error handler with the new error
});
if (process.env.NODE_ENV === 'development') {
// only use in development
app.use(errorhandler())
}
Source code distributed under the MIT license. Text and other assets copyright General Assembly, Inc., all rights reserved.