Sidebar: Express routing organization

The lack of opinions expressed by ExpressJS is one of the things that draws people to it, but it makes it hard as soon as you start considering what anything past a trivial size looks like. In particular, one of the first things you run into is where to put the routes. A bunch of other people have run into the same thing – a blog post, a GitHub repository, a GitHub issue, a StackOverflow answer. Either way, it seems like the Express generator doesn’t build the optimal structure for an app to grow – surprise surprise. I’ll rejigger my routes in anticipation, and see how it pans out. I don’t have enough experience to really know what’s a good direction to go with this. I do know that the way Rails organizes things – all the controllers in one area, all the views somewhere else – doesn’t seem to scale well. Any time you’re working on a view, you’ll also probably want to work on the controller, so why not co-locate them.

Functionally speaking this isn’t changing anything, the intention here is only to organize things so that they’re a bit easier to manage. Originally I had created a min-auth-server/routes/users/index.js structure, but that didn’t quite sit right with me. It’s not that it was wrong per se, just that I wasn’t confident it was a modern best practice. Instead, I’ve opted to go with a min-auth-server/users/router.js file. The rationale behind that is largely covered here. I’ll also rejigger it a bit to separate the actual routing from the functions the routes invoke – not into different files, as that’s not necessary yet, but still worth doing I think.

// min-auth-server/users/routes.js

module.exports = function (router) {
  var signIn = function (req, res) {
    res.status(200).json({ message: "To-do: implement this..." });
  }

  var signUp = function (req, res) {
    res.status(200).json({ message: "To-do: implement this..." });
  }

  var signOut = function (req, res) {
    res.status(200).json({ message: "To-do: implement this..." });
  }

  router.post('/users/sign-in', signIn);
  router.post('/users/sign-up', signUp)
  router.post('/users/sign-out', signOut)

  return router;
}

And we’ll have to update the app.js as well.

// app.js

...
- const userRoutes = require('./routes/users');
...
- app.use(userRoutes);
+ app.use('/api', require.main.require("../users/router")(express.Router()));
...

This feels a little bit cleaner to me, and I’m eager to try out grouping by “subject” instead of “type” – e.g. the user router lives next to the user DAO, which lives next to the user utility functions. The downfall is always the grey areas, which is perhaps why Ruby on Rails has gone the direction it has, but hopefully those will be few and far between.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s