Avoid manually prepending '/api' to every Express route with this simple method

Corey Cleary - Oct 23 '18 - - Dev Community

Originally published at coreycleary.me. This is a cross-post from my content blog. I publish new content every week or two, and you can sign up to my newsletter if you'd like to receive my articles directly to your inbox! I also regularly send cheatsheets, links to great tutorials by other developers, and other freebies!

Have you ever been frustrated by having to always manually add '/api' to the beginning of each of your Express routes? Usually I see this come in two forms:

Form 1:
In app.js file:

app.use('/api/users', require('./routes/users'))
app.use('/api/posts', require('./routes/posts'))
app.use('/api/comments', require('./routes/comments'))
app.use('/api/subscriptions', require('./routes/subscriptions'))

Form 2:
In routes file:

router.post('/api/users', users.createUser)
router.post('/api/posts', blogpost.postBlogpost)
router.post('/api/comments', comment.postComment)
router.post('/api/subscriptions', subscription.addSubscription)

Either way- it looks messy, you have to remember to add it each time if you aren't copying/pasting, and it seems like there should be a better way of doing it.

Let's clean it up

Fortunately, the fix for this is really simple.

In our routes file, remove '/api' from each route

const express = require('express')
const router = express.Router()

router.post('/users', users.createUser)
router.post('/posts', blogpost.postBlogpost)
router.post('/comments', comment.postComment)
router.post('/subscriptions', subscription.addSubscription)

module.exports = router

And in app.js (or server.js, wherever you setup your Express server):

const express = require('express')
const app = express()
const routes = require('./routes')

app.use('/api', routes) // routes is our routes file above

So instead of prepending '/api' manually to each route, we import the Express router into app.js and prepend '/api' - this time, only once! - to app.use()

How does this work?

What we've essentially done here is composed a pipeline.

Let's consider app as our main app and router (our routes file) as a "sub-app".

When our application receives a web request, it will hit app.use('/api', routes) first. If the request was sent to an endpoint matching something like '/api/blah/blah' it will match on app.use('/api', routes) and from there, get routed to our sub-app router, which contains the rest of our routes.

So Express builds out this pipeline for you, and you don't have to manually add '/api' to each route anymore!

One last thing!

I'm writing a lot of new content to help make Node and JavaScript easier to understand. Easier, because I don't think it needs to be as complex as it is sometimes. If you enjoyed this post and found it helpful here's that link again to subscribe to my newsletter!

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