Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

codeA guest post by Roman Shtylman, founder of Courseoff, an online student scheduling tool. Courseoff uses Express.js for all their web services. He has been involved in open source for many years and is a contributor to many open source projects, Express.js being one of them. His current development passion is for JavaScript and Node.js and he frequently evangelizes new tools and techniques in the JavaScript ecosystem. He can be found on Twitter @defunctzombie.

If you haven’t read them already, take a look at the two previous posts on Express.js that I have written: Express.js Middleware Demystified and Error Handling in Express.js Applications.

When building REST APIs with Express.js, it is common to see resource URLs that follow the pattern <collection>/<item-id>/some-item-subpath, for instance /users/12345/profile_url. While it is not always the case, this typically involves looking up the user (specific by user id 12345) and then returning the sub-resource (profile_url in our example).

For this route, you might write something like the following:

The steps here are pretty clear.

  1. Lookup the user based on the user_id in the URL.
  2. Query for the user in some database.
  3. Respond with the user’s profile_url (or 404 if you couldn’t find the user).

This works great and is exactly the functionality we wanted in our route!

Scaling up!

What happens, however, when you have many routes under /users/:user_id? Not only would it be annoying to type all of the code to load a user over and over, but it would also be error prone and hard to maintain. If for some reason you need to change how to query the database for a user, you now have to update every place this happens!

Imagine you need to load the user for the following routes:

Instead of copy and pasting the same user loading logic, you can use the named parameter features of Express.js routers to load a user for all these routes from a single function!

The first thing you need to do is define how the user_id parameter will be handled. For that, use the .param() method.

The .param() method takes the name of the parameter (user_id in this case) and a function. The function signature is similar to route signatures, but has one extra argument at the end. This argument will contain the value of the parameter.

The function body looks similar to what we had in our route above with a few minor, but important details.

  1. We don’t respond to the request.
  2. The user we find in the database is set as a property on the req object.
  3. next() is invoked to let Express.js know we are done loading the parameter and to proceed with the route handler.

It is important that you invoke next whenever you are done, otherwise your requests will appear to stall.

The choice of req.user was arbitrary and you may user other properties. Be mindful of stomping on values, since the req and res objects you modify are the same ones visible to all routes in the app.

Now let’s add our actual routes.

Notice that there is no user database loading logic in any of these routes! Instead, we access the req.user property, which would be the user object.

Also notice there is no logic to check that req.user exists. Our routes would not have run if the user was not found or if there was an error loading the user because next(err) would skip the routes and invoke error handlers instead.

Final Thoughts

Named parameters in Express.js are a great tool for the rapid development of many routes that minimize duplicate code. We have a maintainable way to load users for any route defined with a user_id parameter. Remember that this is only one way you can leverage named parameters; maybe your API setup or data models don’t require loading the full user for all /users/:user_id requests. Be mindful of extra requests your app may be doing that can impact your final response times.

Here are some important tips to keep in mind:

  • Don’t forget to call next() once you are done loading the parameter.
  • Passing errors to next(err) will skip your routes and go right to the error handlers.

Be sure to spend some time examining the great books below that cover Express.js from Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Professional Node.js: Building Javascript Based Scalable Software begins with an overview of Node.js and then quickly dives into the code, core concepts, and APIs. In-depth coverage pares down the essentials to cover debugging, unit testing, and flow control so that you can start building and testing your own modules right away.
JavaScript Programming: Pushing the Limits delivers a compelling tutorial, showing you how to build a real-world app from the ground up. Experienced developers who want to master the latest techniques and redefine their skills will find this deep dive into JavaScript’s hidden functionalities gives them the tools to create truly amazing and complex applications.
Smashing CoffeeScript is a full-color, practical book that explains the CoffeeScript language, syntax, and processes, and will soon have you producing concise and quality code. Ultimately, you’ll create RIAs and mobile apps faster, with less hassle.
Node.js Recipes: A Problem-Solution Approach is your one-stop reference for learning how to solve Node.js problems. Node.js is the de facto framework for building JavaScript-powered servers. You will first be introduced to this exciting technology and what it can do, then learn through comprehensive and easy-to-follow recipes that use a problem-solution approach. This book teaches you to fully use the Node.js API, and leverage existing modules to build truly exciting projects.

Tags: Express.js, next, Parameterized Routes, req.user, REST APIs, routes, scaling up,

One Response to “Parameterized Routes in Express.js”

  1. RichD

    Helpful post… How would the routing code look under Express 4? Thanks!