More About Routing with Express

John Au-Yeung - Jan 24 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Routing is the most important part of a back end application. Express allows us to route URLs to our route handler code easily.

In this article, we’ll look at how to create different kinds of routes with Express.

Handling All Requests

We can use the app.all method to handle all request methods. To use it, we can write something like the following:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.all('*', (req, res, next) => {  
  console.log('route called');  
  next();  
})

app.get('/', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

The app.all call above will be invoked when any method or URL is sent. It’ll log 'route called' and then call next to call the specific route handler for that route.

Non-Letter Symbols

Express can match routes with non-letter symbols. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/foo.bar', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then when we make a GET request to foo.bar then we get hi .

Special Characters

Optional Character

If the ? is in a URL path, then it’s considered an optional character. For example, ab?c matches ac or abc .

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab?c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then when we make a request to /ac or /abc , we get hi .

One or More Character

If a URL has a + sign, then it’ll match one or more of the character preceding it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab+c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then when making a request to /abc , /abbc , /abbbc and so on, we’ll get hi .

Wildcard

The * in the URL is a wildcard character.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab\*c', (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then we put anything between ab and c in the URL and get the hi response.

Optional Character Group

A character group is optional if it’s surrounded by parentheses and has a ? after it.

For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/ab(cd)?ef', (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then when we go to /abcdef or /abef , we get hi .

Regular Expressions

We can also use regular expressions as route paths. For example, if we have:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/a/, (req, res) => {  
  res.send('hi');  
})
app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then when we make a request to /a , we get hi .

To get hi when we make any request with path that ends with foo , we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get(/\/.\*foo$/, (req, res) => {  
  res.send('hi');  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Route Parameters

We can designate parameters by writing a colon before the key name of the parameter.

For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/:name/:age', (req, res) => {  
  res.send(req.params);  
})

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then we get the following response:

{"name":"Mary","age":"10"}
Enter fullscreen mode Exit fullscreen mode

:name and :age are interpreted as route placeholders. req.params will use them as the keys without the colon. Then whatever is set in the place of the placeholders will be the corresponding values.

Route Handlers

The callback in the second argument of the app.get above are route handlers. The same can be done for POST, PUT and DELETE requests by replacing app.get with app.post , app.put and app.delete respectively.

We can chain multiple handlers together with the next function. For example, we can write:

const express = require('express')  
const app = express()
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/',  
  (req, res, next) => {  
    console.log('handler 1 called');  
    next()  
  },  
  (req, res) => {  
    console.log('handler 2 called');  
    res.send();  
  })

app.listen(3000, () => console.log('server started'));
Enter fullscreen mode Exit fullscreen mode

Then we should see:

handler 1 called  
handler 2 called
Enter fullscreen mode Exit fullscreen mode

in the console.log output.

We call the next function which originates from the route handler’s parameter to call the next route handler function.

Conclusion

Routing with Express is simple. We can use strings or regular expressions to specify our route paths.

Some characters in string paths like ? , +, or * are special characters for paths with optional characters or wildcards.

Placeholders for route parameters are specified by using a colon in front of the placeholder name.

We call next to chain multiple route handlers together.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .