As you begin implementing routes, you will quickly see that for complex systems, the number of routes can get out of hand. To reduce the number of routes, you can implement parameters within the URL. You can use parameters to use the same route for similar requests by providing unique values for different requests that define how your application handles requests and builds responses.
For example, you would not have a separate route for every user or product in your system. Instead, you would pass in a user ID or product ID as a parameter to one route, and the server code would use that ID to determine which user or product to use. There are four main methods for implementing parameters in a route:
Query strings: You can use the standard ?key=value&key=value...
HTTP query string after the path in a URL. This is the most common method for implementing parameters, but the URLs can become very long and convoluted.
POST params: When implementing a web form or another POST
request, you can pass parameters in the body of the request.
Regexes: You can define a regular expression as the path portion of the route. Express uses the regex to parse the path of the URL and stores matching expressions as an array of parameters.
Defined parameters: You can define a parameter by name by using :<parm_name>
in the path portion of the route. Express automatically assigns that parameter a name when it parses the path.
The following sections discuss all these methods except POST
params, which are covered in Chapter 19, “Implementing Express Middleware.”
The simplest way to add parameters to a route is to pass them using the normal HTTP query string format ?key=value&key=value...
and then use the url.parse()
method to parse the url
attribute of the Request
object to get the parameters.
The following code implements a basic GET
route to /find?author=<author>&title=<title>
that accepts author
and title
parameters. To actually get the value of author
and title
, the url.parse()
method builds a query object:
var express = require('express'),
var url = reauire('url'),
var app = express();
app.get('/find', function(req, res){
var url_parts = url.parse(req.url, true);
var query = url_parts.query;
res.send('Finding Book: Author: ' + query.author +
' Title: ' + query.title);
});
For example, consider the following URL:
/find?author=Brad&title=Node
The res.send()
method returns:
Finding Book: Author: Brad Title: Node
A great method of implementing parameters in routes is to use a regular expression to match patterns. Using regexes allows you to implement patterns that do not follow a standard / formatting for the path.
The following code implements a regex parser to generate route parameters for GET
requests at the URL /book/<chapter>:<page>
path:
app.get(/^/book/(w+):(w+)?$/, function(req, res){
res.send('Get Book: Chapter: ' + req.params[0] +
' Page: ' + req.params[1]);
});
Notice that the values of the parameters are not named. Instead, req.params
is an array of matching items in the URL path.
For example, consider the following URL:
/book/12:15
The res.send()
method returns:
Get Book: Chapter: 12 Page: 15
If your data is more structured, then instead of using regexes, you can use defined parameters. Using a defined parameter allows you to define your parameters by name within the route path. You define parameters in the path of the route by using :<param_name>
. When using defined parameters, req.param
is a function instead of an array, and calling req.param(param_name)
returns the value of the parameter.
The following code implements a basic :userid
parameter that expects a URL with a /user/<user_id>
format:
app.get('/user/:userid', function (req, res) {
res.send("Get User: " + req.param("userid"));
});
For example, consider the following URL:
/user/4983
The res.send()
method returns:
Get User: 4983
A major advantage of using defined parameters is that you can specify callback functions that are executed if the defined parameter is found in a URL. When parsing the URL, if Express finds a parameter that has a callback registered, it calls the parameter’s callback function before calling the route handler. You can register more than one callback function for a route.
To register a callback function, you use the app.param()
method. The app.param()
method accepts the defined parameter as the first argument and then a callback function that receives the Request
, Response
, next
, and value
parameters:
app.param(param, function(req, res, next, value){} );
The Request
and Response
objects are the same as the objects passed to the route callback. The next parameter is a callback function for the next app.param()
callback registered, if any. You must call next()
somewhere in your callback function, or the callback chain will be broken. The value parameter is the value of the parameter parsed from the URL path.
For example, the following code logs every request that is received that has the userid
parameter specified in the route. Notice the call to next()
before leaving the callback function:
app.param('userid', function(req, res, next, value){
console.log("Request with userid: " + value);
next();
});
To see how this code works, consider the following URL:
/user/4983
The userid
parameter setting of 4983
is parsed from the URL, and the console.log()
statement displays:
Request with userid: 4983
Listing 18.2 provides an example of implementing query strings, regex, and defined parameters with Express routes. Lines 8–16 implement the query string method. Lines 17–23 implement the regex method. Lines 24–33 implement a defined parameter along with a callback function that is executed whenever the userid
parameter is specified in the request parameters. Figure 18.1 shows the console output from the code in Listing 18.2.
01 var express = require('express'),
02 var url = require('url'),
03 var app = express();
04 app.listen(80);
05 app.get('/', function (req, res) {
06 res.send("Get Index");
07 });
08 app.get('/find', function(req, res){
09 var url_parts = url.parse(req.url, true);
10 var query = url_parts.query;
11 var response = 'Finding Book: Author: ' + query.author +
12 ' Title: ' + query.title;
13 console.log('
Query URL: ' + req.originalUrl);
14 console.log(response);
15 res.send(response);
16 });
17 app.get(/^/book/(w+):(w+)?$/, function(req, res){
18 var response = 'Get Book: Chapter: ' + req.params[0] +
19 ' Page: ' + req.params[1];
20 console.log('
Regex URL: ' + req.originalUrl);
21 console.log(response);
22 res.send(response);
23 });
24 app.get('/user/:userid', function (req, res) {
25 var response = 'Get User: ' + req.param('userid'),
26 console.log('
Param URL: ' + req.originalUrl);
27 console.log(response);
28 res.send(response);
29 });
30 app.param('userid', function(req, res, next, value){
31 console.log("
Request received with userid: " + value);
32 next();
33 });