Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hierarchical routing with plain Express.js

I’m implementing a RESTful API using Node and Express. When it comes to routing, currently it looks like this:

var cat = new CatModel();
var dog = new DogModel();

app.route('/cats').get(cat.index);
app.route('/cats/:id').get(cat.show).post(cat.new).put(cat.update);

app.route('/dogs').get(dog.index);
app.route('/dogs/:id').get(dog.show).post(dog.new).put(dog.update);

I don’t like this for two reasons:

  1. Both cat and dog models are instantiated whether I need them or not.
  2. I have to repeat /cats and /dogs for every path schema

I’d love to have something like this (not working, of course):

app.route('/cats', function(req, res)
{
    var cat = new CatModel();

    this.route('/').get(cat.index);
    this.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});

app.route('/dogs', function(req, res)
{
    var dog = new DogModel();

    this.route('/').get(dog.index);
    this.route('/:id').get(dog.show).post(dog.new).put(dog.update);
});

Is there a clean way in modern Express without any further modules (like express-namespace)? I could go for separate routers for each model and assigning them with app.use('/cats', catRouter). However, what if I have more than one hierarchy level like '/tools/hammers/:id'? I would then have routers within routers within routers, which seems like overkill to me.

like image 542
Rob Avatar asked Apr 28 '14 04:04

Rob


People also ask

What is routing and how routing works in Express JS?

Routing refers to how an application's endpoints (URIs) respond to client requests. For an introduction to routing, see Basic routing. You define routing using methods of the Express app object that correspond to HTTP methods; for example, app.get() to handle GET requests and app.post to handle POST requests.

What is hierarchical routing explain with example?

Hierarchical routing is the procedure of arranging routers in a hierarchical manner. A good example would be to consider a corporate intranet. Most corporate intranets consist of a high speed backbone network. Connected to this backbone are routers which are in turn connected to a particular workgroup.

How is it possible to create Chainable route handlers for a route path in Express JS?

By using app.route() method, we can create chainable route handlers for a route path in Express.js.

How do I nest a route in Express?

You can nest routers by attaching them as middleware on an other router, with or without params . You must pass {mergeParams: true} to the child router if you want to access the params from the parent router. Save this answer.


2 Answers

I would then have routers within routers within routers, which seems like overkill to me.

Perhaps, but that is the built-in method of prefixing -- to app.use() a Router().

var cats = express.Router();
app.use('/cats', cats);

cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);

// ...

And, to have one Router .use() another to define multiple depths:

var tools = express.Router();
app.use('/tools', tools);

var hammers = express.Router();
tools.use('/hammers', hammers);

// effectively: '/tools/hammers/:id'
hammers.route('/:id').get(...);

Though, to be closer to your 2nd snippet, you can define a custom method:

var express = require('express');

express.application.prefix = express.Router.prefix = function (path, configure) {
    var router = express.Router();
    this.use(path, router);
    configure(router);
    return router;
};

var app = express();

app.prefix('/cats', function (cats) {
    cats.route('/').get(cat.index);
    cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});

app.prefix('/dogs', ...);

app.prefix('/tools', function (tools) {
    tools.prefix('/hammers', function (hammers) {
        hammers.route('/:id').get(...);
    });
});
like image 85
Jonathan Lonowski Avatar answered Oct 08 '22 01:10

Jonathan Lonowski


Check out the new Router in Express 4. It sounds exactly what you're looking for.

like image 30
mscdex Avatar answered Oct 08 '22 01:10

mscdex