4

I'd like to be able to mount a whole express sub-app on a uri containing a parameter. I've something similar to the following:

in app.js:

var app_authors = require('./api/authors');
var app = express();
...
app.use('/api/authors', app_authors);
...
module.exports = app;

in api/authors.js:

var app_author_books = require('./api/books');
var app = express();
...
app.get('/:author', ...);
...
app.use('/:author/books', app_author_books);
...
module.exports = app;

While the first sub-app works, mounted over /api/authors, the nested one doesn't (urls of the form /api/authors/:author/books and similar are not recognized)

EDIT:

For the curious, AFAIK sub-apps are not very clearly documented, but they should work, at least according to TJ Holowaychuk's Modular web applications with Node.js and Express (and the related vimeo screencast). See also this other SO answer.

Community
  • 1
  • 1
Marco Pantaleoni
  • 2,529
  • 15
  • 14
  • try defining the `app_author_books` function inline instead of requiring `./api/authors`. also try adding a trailing slash to the path in app.js at `app.use('/api/authors', app_authors);` – Plato Dec 17 '13 at 16:56
  • @Plato while that would likely work, it seems that your answer is just avoiding the main question. While it would be fine to write it inline (or reference a function) for one route, it is cumbersome if `app_author_books` contains multiple routes (perhaps a RESTful interface for all books). – Nick Mitchinson Dec 17 '13 at 18:06
  • what @NickMitchinson says is correct: app_author_books is a sub-app, containing many routes – Marco Pantaleoni Dec 17 '13 at 21:07
  • well, as [docs](http://expressjs.com/api.html#app.use) mention, the sub-apps don't see the prefix. could you swap 'em? in app.js: `app.use('/books/', app_author_books)`; and in authors.js: `app.get('/:author', function(){...}` with new path `/api/books/:author` – Plato Dec 17 '13 at 21:54
  • regarding the visibility of the prefix, you are right, but I'm using [app.param()](http://expressjs.com/api.html#app.param) to populate `req` with the object derived from `:author`, so this limitation is a non-issue. And unfortunately I can't swap the sub-apps (because the inner one is dependent on the author object instance...) – Marco Pantaleoni Dec 18 '13 at 20:40

2 Answers2

0

It seems that you want to create different "applications" to separate the routes/services in different files.

You should try the approach given here in which they pass the app variable as a parameter, and hence, you only have one application that controls all the routes (that are located in your separate files).

I hope this is what you're looking for.

Community
  • 1
  • 1
Danilo Ramirez
  • 1,598
  • 1
  • 16
  • 22
  • I'm aware of that approach, but I'd really like to use sub-apps instead of a single giant app. sub-apps are supported by express, see for example [Modular web applications with Node.js and Express](http://vimeo.com/56166857) and [this](http://stackoverflow.com/a/8514234/1363486) SO answer. – Marco Pantaleoni Dec 17 '13 at 21:10
  • Oh, sorry...I interpreted the question wrong. Time for me to study more Express sub-apps! – Danilo Ramirez Dec 18 '13 at 14:59
0

In Express 4, when you mount a sub-app on a path (or a regex), this path is removed from req.path (but is still in req.originalUrl).

See this github issue and Express 4 doc about mountpoints.

nlc
  • 65
  • 1
  • 5