Express.js USES elaboration

  • 2020-03-30 03:31:12
  • OfStack

After node(download) is installed, create a directory on your machine and start your first application.


$ mkdir hello-world

In this directory you will define the application "package", which is no different from any other node package. The json file in the file directory explicitly defines a dependency. You can use the NPM command to get the latest version of express, which you prefer to do instead of installing a version other than "3.x" to prevent any unknown surprises.


{
 
"name": "hello-world",
 
"description": "hello world test app",
 
"version": "0.0.1",
 
"private": true,
 
"dependencies": {
  "express": "3.x"
}
}

Now you have a package. Json files in this directory you can use NPM (1) to install this dependency, in which case you just need to type:


$ npm install

Once the NPM is complete, you will have an Express 3.x that you rely on in the /node_modules directory. You can verify this with NPM ls, as shown in the following code snippet with the Express tree and its own dependencies.


$ npm ls
hello-world@0.0.1 /private/tmp
 └ ─ ┬  express@3.0.0beta7
  ├ ─ ─  commander@0.6.1
  ├ ─ ┬  connect@2.3.9
  │   ├ ─ ─  bytes@0.1.0
  │   ├ ─ ─  cookie@0.0.4
  │   ├ ─ ─  crc@0.2.0
  │   ├ ─ ─  formidable@1.0.11
  │   └ ─ ─  qs@0.4.2
  ├ ─ ─  cookie@0.0.3
  ├ ─ ─  debug@0.7.0
  ├ ─ ─  fresh@0.1.0
  ├ ─ ─  methods@0.0.1
  ├ ─ ─  mkdirp@0.3.3
  ├ ─ ─  range-parser@0.0.4
  ├ ─ ┬  response-send@0.0.1
  │   └ ─ ─  crc@0.2.0
  └ ─ ┬  send@0.0.3
   └ ─ ─  mime@1.2.6

Now create the application itself! Create a file called app.js or server.js, whichever you like, introduce express, and then use express() to create a new application:


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

The new application instance can begin to define the route by app-verb (), in which case the "GET/" request is answered by the "Hello World" string. Req and res are the exact same node objects that are provided to you, so you might call res.pipe(),req.on('data', callback), and other express-independent things you would do.

Express enhancements these objects provide you with higher-level interfaces such as res.send(), in addition to adding content length:


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

Now bind and listen for the connection by calling the app.listen() method, which accepts the same parameters as the node net.server #listen():


var server = app.listen(3000, function() {
  console.log('Listening on port %d', server.address().port);
});

Use express(1) to generate the application

The Express team maintains a convenient project generator, named express-generator (1). If you install express-generator globally with NPM, you can access it from anywhere on your computer:


$ npm install -g express-generator

Like any other node application, you must install the following dependencies:

Then let's get started.


$ npm start

This is all you need to get a simple application up and running. Remember,Express is not tied to any particular directory structure, these are just a guide. A selection of application structures can be viewed as an example in the github repository.

Error handling

The error handling middleware definition is just like ordinary middleware, but must define the number of four parameters, which is the function signature (err, req, res, next):


app.use(function(err, req, res, next){
 console.error(err.stack);
 res.send(500, 'Something broke!');
});

While mandatory error-handling middleware is not usually defined last, after other app.use(), its invocation is as follows:


var bodyParser = require('body-parser');
var methodOverride = require('method-override');
app.use(bodyParser());
app.use(methodOverride());
app.use(app.router);
app.use(function(err, req, res, next){
 // logic
});

To build an organized and higher-level framework, you can define several of these error-handling middleware, just as you would define plain middleware. For example, suppose you want to define an error handler for an XHR request. In addition to this, you might do the following:


var bodyParser = require('body-parser');
var methodOverride = require('method-override'); 

app.use(bodyParser());
app.use(methodOverride());
app.use(app.router);
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);

In the more general logErrors can write requests and error messages to stderr, loggly, or similar services:


function logErrors(err, req, res, next) {
 console.error(err.stack);
 next(err);
}

The definition of the clientErrorHandler is shown below. Note that this error is explicitly passed to the next one.


function clientErrorHandler(err, req, res, next) {
 if (req.xhr) {
  res.send(500, { error: 'Something blew up!' });
 } else {
  next(err);
 }
}

The following "omnidirectional" implementation of errorHandler can be defined as:


function errorHandler(err, req, res, next) {
 res.status(500);
 res.render('error', { error: err });
}

User online counting

This section covers the full details of a (small) application that USES Redis to track the number of users online. First, create a package. The json file contains two attachments, one for the redis client and one for Express itself. Also make sure you wrap redis and run it through $redis-server.


{
 "name": "app",
 "version": "0.0.1",
 "dependencies": {
  "express": "3.x",
  "redis": "*"
 }
}

Next, you need to create an application and a connection to redis:


var express = require('express');
var redis = require('redis');
var db = redis.createClient();
var app = express();

The next middleware tracks online users. Here we will use sorted sets so that we can query online users through redis in N milliseconds. We use timestamps as an "online standard" for members. Note that here we use the user-agent string instead of the usual user id.


app.use(function(req, res, next){
 var ua = req.headers['user-agent'];
 db.zadd('online', Date.now(), ua, next);
});

The next middleware is to use zrevrangebyscore at the last minute to get the maximum number of online users, we always get the most recent online users, his upper limit is the current timestamp minus 60,000 milliseconds.


app.use(function(req, res, next){
 var min = 60 * 1000;
 var ago = Date.now() - min;
 db.zrevrangebyscore('online', '+inf', ago, function(err, users){
  if (err) return next(err);
  req.online = users;
  next();
 });
});

Finally, we use it through a url and bind to a port! That's the end of the story. Access the application in a new browser and you'll see an increase in the number of people online.


app.get('/', function(req, res){
 res.send(req.online.length + ' users online');
});

app.listen(3000);

Expree's reverse proxy

Using Expree, such as Varnish or Nginx, behind the reverse proxy is trivial, however it requires configuration. By enabling "trust agency" set up the app. The enable (" trust "proxy), Express some reverse proxy technique, X-ray Forwarded - * header fields can be trusted, otherwise they could easily be cheat.

Enabling this setting has some subtle effects. The first is the X - Forwarded - Proto may be reverse proxy Settings, tell the app that is HTTPS or just a simple HTTP. This value is reflected by req.protocol.

The second change is the req. IP and the req. Ips value will populate the X - Forwarded - For a list of addresses.

Debugging Express

Express internally USES the debug module to record information about path matching and application patterns. To see this message, simply set the debug environment variable to express:*, and when you launch the application, you'll see it on the console to debug the message.


$ DEBUG=express:* node ./bin/www

Running the hello world example will print the following:


express:application booting in development mode +0ms
express:router defined get /hello.txt +0ms
express:router defined get /hello.txt +1ms

In addition, programs that express executable (generator) generation also use the debug module, and the default scope is the my-application debug namespace.

You can enable these debug statements with the following command


$ DEBUG=my-application node ./bin/www

For more information on debugging, see debugging (link: https://github.com/visionmedia/debug)


Related articles: