ExpressJS

nodejs
nodejs-frameworks

Articles
Resources

http://expressjs.com/4x/api.html
http://expressjs.com/api.html
http://www.sitepoint.com/5-easy-performance-tweaks-node-js-express/
http://www.sitepoint.com/express-yourself/
https://medium.com/@nodejs/q-a-with-express-gateway-team-a-microservice-api-gateway-built-on-express-ebb3b18b5bdb

npm

Routes
Middlewares
Configuration
Static resources
Template engines
Session handling
Authentication
Admin panel
Socket.IO
Debugging
Logging
Error handling
Environment variables
MVC

What is ExpressJS?

Fast, unopinionated, minimalist web framework for Node.js, more like Sinatra. Express was one of the first really popular frameworks for Node.js, and for good reason: It's incredibly slick (based on the Sinatra framework for Ruby), and VERY well-documented. Express is geared toward very dynamic, but small web applications. If you're comfortable with most of your controller/business logic being in a single javascript file, Express is a fantastic choice. It's based on Connect, so all that juicy juicy middleware for logging and gzipping and caching is available to you as well. A very well-rounded framework for small applications. With a myriad of HTTP utility methods and middleware at your disposal, creating a robust API is quick and easy.

How can we install Express?

npm install -g express
npm install -g express@3.4.3
npm install express-generator -g

express -h

// Alternatively, we can create a directory for our application, and inside this directory:
npm init
npm install express --save

// To install Express temporarily, and not add it to the dependencies list, omit the --save option:
npm install express

Node modules installed with the —save option are added to the dependencies list in the package.json file. Then using npm install in the app directory will automatically install modules in the dependencies list.

How can we install all the dependencies for an application?

After we just check out an application from the source repository, go inside the application folder and run:

npm install

What are the benefit of install Express globally?

npm install -g express

By doing this, you now have a brand new CLI instrument. For example if you run:

express --sessions --css less --hogan app
npm install

Express will scaffold an application skeleton with a few things already configured for you. Here are the usage options for the express(1) command:

Usage: express [options]
Options:
  -h, --help          output usage information
  -V, --version       output the version number
  -s, --sessions      add session support
  -e, --ejs           add ejs engine support (defaults to jade)
  --hbs    add handlebars engine support
  -J, --jshtml        add jshtml engine support (defaults to jade)
  -H, --hogan         add hogan.js engine support
  -c, --css   add stylesheet  support (less|stylus|compass|sass) (defaults to plain css)
  -f, --force         force on non-empty directory

When the above command finishes, our project looks like the following:

/public
    /images
    /javascripts
    /stylesheets
/routes
    /index.js
    /user.js
/views
    /index.hjs
/app.js
/package.json

If you check out the package.json file, you will see that all the dependencies which we need are added here. Although they haven't been installed yet. To do so, just run npm install and then a node_modules folder will pop up.

The main file is app.js. To start the application:

node app.js

The main index.html is in /views/index.hjs file, and the routes are defined in the routes folder.

So, we can easily send command line arguments which will define the current environment. I wrapped that part in a separate module in order to write a test for it later. Here is the /config/index.js file:

var config = {
    local: {
        mode: 'local',
        port: 3000
    },
    staging: {
        mode: 'staging',
        port: 4000
    },
    production: {
        mode: 'production',
        port: 5000
    }
}
module.exports = function(mode) {
    return config[mode || process.argv[2] || 'local'] || config.local;
}

There are only two settings (for now) - mode and port. As you may guess, the application uses different ports for the different servers. To use the above configuration file in our app.js file:

var config = require('./config')();
...
http.createServer(app).listen(config.port, function(){
    console.log('Express server listening on port ' + config.port);
});

To switch between the configurations, just add the environment at the end. For example:

node app.js staging

This works because the /config/index.js file contains:

module.exports = function(mode) {
    return config[mode || process.argv[2] || 'local'] || config.local;
}

which exports just the configuration object appropriate for the environment specified on the command line.

How can we write automated tests for our application?

npm install -g jasmine-node

Let's create a tests directory which will hold our tests. The first thing that we are going to check is our configuration setup. The spec files must end with .spec.js, so the file should be called config.spec.js:

describe("Configuration setup", function() {
    it("should load local configurations", function(next) {
        var config = require('../config')();
        expect(config.mode).toBe('local');
        next();
    });
    it("should load staging configurations", function(next) {
        var config = require('../config')('staging');
        expect(config.mode).toBe('staging');
        next();
    });
    it("should load production configurations", function(next) {
        var config = require('../config')('production');
        expect(config.mode).toBe('production');
        next();
    });
});

To run our tests:

jasmine-node ./tests

Each time you start writing a new class, a new module, or just a new piece of logic, ask yourself: How can I test this?

How can we use the express generator to generate a skeleton app?

See the example usage of the express command from above.

How can we start our Express 4 app?

npm start

Do we have to use the structure that is produced by the generator?

No. The app structure generated by the generator is just one of the multiple ways of structuring Express apps. Feel free to not use it or to modify it to best suit your needs.

What is the purpose of the package.json file?

It specifies all the modules that your application needs or depends on.

How can we add a dependency for our application?

Add it to the package.json file and then run:

npm install

How can we create a small bare bone app?

Let's go back to the application we created with the previous package.json file and add an app.js file:

// app.js:
var express = require('express');
var app = express();

// define various routes:
app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.listen(3000);

and quickly run it:

node app

How can we display something to the console when we start the application?

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

How does Express handle JSON response?

Express adds a simple send() method to the response object. This abstracts away some of the boilerplate code to handle responses. The request.send() API also intelligently handles different types of data. Imagine you want to add a simple JSON-based API to your site. By simply returning an object instead of a string, Express will handle converting the result to JSON as well as setting the appropriate response headers.

app.get('/api', function(request, response) {
    response.send({name:"Raymond",age:40});
});

Alternatively, we can use the res.json method:

app.get('/api/v1/stories/:id', function(req,res){
  res.json(req.story);
});

which is equivalent to:

app.get('/api/v1/stories/:id', function(req,res){
  res.send(req.story);
});

or:

app.get('api/v1/stories/:id',function(req,res){
  res.set({
    'Content-Type': 'application/json'
  });
  res.send(req.story);
});

How can we build a static site with Express?

var express = require('express');
var app = express();

app.get('/', function(req, res) {
    res.sendfile('./views/index.html');
});

app.get('/about', function(req, res) {
    res.sendfile('./views/about.html');
});

app.get('/article', function(req, res) {
    res.sendfile('./views/article.html');
});

app.listen(3000);

Some times we just need a lightweight static site. If that is the case, we should just use Apache to serve static files. The above example just demonstrate using sendfile.

How can we send a static file?

app.get('/article', function(req, res) {
    res.sendfile('./views/article.html');
});

What template engines can be used with Express?

Express supports a variety of templating engines (Jade, EJS, JSHTML, Hogan, etc). According to the Express documentation, any templating engine that conforms to a particular signature (path, locals, callback) will work with it. They also recommend checking the consolidate.js library for a list of supported template engines.

How can we use Handlebars with Express?

In order to use Handlebars you need to install a wrapper library called hbs. Let's add this to our application's package.json file:

npm install hbs --save

and update our app.js:

var express = require('express');
var app = express();

var hbs = require('hbs');

app.set('view engine', 'html');
app.engine('html', hbs.__express);

app.get('/', function(req, res) {
    res.render('index', {title: 'Home'});
});

app.get('/about', function(req, res) {
    res.render('about', {title: 'About'});
});

app.get('/article', function(req, res) {
    res.render('article', {title: 'Articles'});
});

app.listen(3000);

We've done a few important things here. To use Handlebars, we load in (via require) the HBS wrapper library. We then need to tell Express to use it. By default, Handlebars will work with files that contain an extension matching the particular engine. In our case, something.hbs. But we can tell Express to treat HTML files as dynamic by using the "view engine" directive, you see above. This is not required, but I prefer working with HTML files. My editor can then provide nicer code hinting and syntax highlighting. Actually loading the engine is then done via app.engine.

Finally, the routes all switch to using the new render method. Express defaults to using the views folder, so we can leave that off. Since Express also knows the extension we prefer, we can forget about that as well. Essentially, res.render('something') equates to telling Express to look for views/something.html, parse it based on the rules of our templating engine, and return it to the browser.

How can we fetch a form parameter?

req.params.id

req is the request object. params is the property that contains the form parameters. id is the name of the form parameter that we want to access.

What is automatic layout support?

When using templating engines in Express you get automatic layout support. That means I can create a generic layout with my site design and Express will inject a particular page's output within it. By convention, this is called layout.something where "something" is the particular extension you are using. Since we used HTML, this will just be layout.html:

<html>
<head>
    <title>{{title}}</title>
</head>
<body>
    {{{body}}}
    <footer>
        <p>
            <a href="/">Home</a> ~ <a href="/about">About Me</a>
        </p>
    </footer>
</body>
</html>

How does Express support static resources?

Express provides a simple way to add support for static resources like images, JavaScript libraries, and style sheets. By simply defining a static folder, any request will for a file will be checked against that particular folder before being compared to routes.

app.use(express.static('public'));

At this point, if you request /foo.css, and the file foo.css exists in the public folder, it will be returned.

How can we send HTTP header?

app.get('/hello.txt', function(req, res){
    var body = 'Hello World';
    res.setHeader('Content-Type', 'text/plain');
    res.setHeader('Content-Length', body.length);
    res.end(body);
});

How can I serve static files from several directories?

You may typically use any middleware several times within your application. With the following middleware setup, and a request for GET /javascripts/jquery.js, the first check would be ./public/javascripts/jquery.js; if it does not exist, then the subsequent middleware will check ./files/javascripts/jquery.js.

app.use(express.static('public'));
app.use(express.static('files'));

How can I prefix a pathname for serving static files?

Connect's generic "mounting" feature allows you to define the pathname "prefix" to which the middleware will be invoked. This effectively behaves as if that prefix string were never part of the path. Suppose you wanted GET /files/javascripts/jquery.js. You could mount the middleware at /files, exposing /javascripts/jquery.js as the req.url, allowing the middleware to serve the file:

app.use('/public', express.static('public'));

How can I render plain HTML?

You don't! There's no need to "render" HTML with res.render(). If you have a specific file, use res.sendFile(). If you are serving many assets from a directory use the express.static() middleware. If you insist on using "render" to render HTML, you can put the HTML into a template file and render it. If you have the HTML as a string, you can send it to the browser with res.send(…)

How can we configure Express to trust your load balancer / proxy?

By enabling the "trust proxy" setting via app.enable('trust proxy'), Express will have knowledge that it's sitting behind a proxy and that the X-Forwarded-* header fields may be trusted. (Otherwise, they are easily spoofed.)

Enabling this setting has several subtle effects. The first is that X-Forwarded-Proto may be set by the reverse proxy to tell the app whether it is https or simply http. This value is reflected by req.protocol.

The second change is that the req.ip and req.ips values will be populated with X-Forwarded-For's list of addresses.

How can we upgrade the express generator?

The command-line tool to generate an Express app is still express, but to upgrade to the new version, you must uninstall the Express 3 app generator and then install the new express-generator. If you already have the Express 3 app generator installed on your system, you must uninstall it as follows:

npm uninstall -g express

Now install the new generator:

npm install -g express-generator

How can we use Mongo with Express?

npm install express --save
npm install mongodb --save

Now, it’s time to create the main file called index.js. It’s the file where we’ll do most of our work. Start off by creating a simple app, connecting it to MongoDB and listening on port 8000:

var express = require('express'),
    MongoClient = require('mongodb').MongoClient,
    app = express(),
    mongoUrl = 'mongodb://localhost:27017/textmonkey';

MongoClient.connect(mongoUrl, function (err, db) {
    if (err) throw 'Error connecting to database - ' + err;

    app.listen(8000, function () {
        console.log('Listening on port 8000');
    });
});

Make sure you have MongoDB installed on your machine. You can use the following command to start it:

mongod --dbpath=/data --port 27017

Other unconfirmed things:

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License