How to mount app.get() routes on a particular path prefix

Brian Beckett picture Brian Beckett · Jun 18, 2013 · Viewed 15.6k times · Source

I'm writing an API using Node.js and Express. My API has GET methods of the form:

/api/v1/doSomething
/api/v1/doSomethingElse

My code is looking something like this:

server.js:

var app = express();
...
var routes = require('./routes')
routes.attachHandlers(app, '/api/v1')

routes/index.js

...
module.exports.attachHandlers = function(app, context) {
    //get a list of all the other .js files in routes
    //for each route, require() it and call it myRoute
    myRoute.attachHandlers(app, context)
}

routes/some-route.js

...
module.exports.attachHandlers = function(app, context) {
    app.get(context + '/doSomething', doSomething)
    app.get(context + '/doSomethingElse', doSomethingElse)
}
...

Effectively I'm passing the context path/mount point down through the app. If somebody were to write a route like the following, though, the context would be lost:

app.get('/doFoo', foo)

Rather than having that part of the API mounted on /api/v1/doFoo it's on /doFoo. I would like to avoid having to pass the context path around like this.

app.use supports mounting middleware on an optional mount path. I have seen references online to mounting an entire Express application on a mount path using app.use. This seems like the sort of thing I want to do, but I'm not sure how to do it or if it's the best solution for my particular use case.

To summarise - I want to mount my app.get() routes with a particular prefix by default. What's the best way of doing this?

Answer

marni picture marni · May 22, 2014

With Express 4.0, the task is much cleaner with the Router. You can create as many routers as you need to nicely partition your app, and then attached them with app.use(). For example:

myapp.js

var express = require("express"),
    router  = express.Router(),
    app     = express(),
    port    = 4000;


// Here we declare our API which will be visible under prefix path
router.get('/', function (req, res) {
    console.log("request to subspace hello");
    res.send({ message: "Hi from subspace /api/v1/"});
});

// we attach our routes under /api/v1
app.use('/api/v1', router);


// here we have direct, root-level routing
app.get('/', function (req, res) {
    console.log("request to rootspace hello");
    res.send({message: "Hi from root /"});
});

app.listen(port);
console.log("App active on localhost:" + port);

Then run

node myapp.js

and visit

http://localhost:4000 and http://localhost:4000/api/v1