5

I'm setting up a web app in express.js, and to keep everything organized, I want to keep each route in its own separate file and keep those files in two folders, one for GET and one for POST. How would I go about doing this?

I want to have a main server.js file and a folder with two subfolders one for GET and one for POST that contain one file for each route

Heres a diagram:

server.js
routes/
├── get/
│   ├── login.js
│   ├── register.js
│   └── home.js
└── post/
    ├── login.js
    └── register.js

3 Answers 3

9

Using express.Router() will allow you to seperate your handlers into different files. you can simply include them in your main server.js simply export the custom router.

i would recommend keeping related functionality together rather than splitting the get and post routes into different directories. for example you might have users.js which handles user related tasks and another documents.js for documents etc. you may also add an app to an app. and routes to other routes.

try

$ npm install -g express-generator
$ express-generator

example:

server.js

var route1 = require('./routes/route_1'); // Include custom router 1
var route2 = require('./routes/route_2'); // Include custom router 2
var app = express();
app.use('/route1', route1);
app.use('/route2', route2);

route_1.js

var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {  // handle specific get/post/etc methods
  ...
});
module.exports = router;

route_2.js

var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
  ...
});
module.exports = router;
Sign up to request clarification or add additional context in comments.

Comments

2

A Domain Driven Design Approach

So principles of DDD (Domain Driven Design) will encourage keeping things that belong together, together (in this case in Domain specific folders). However, I agree with @Fattie in that keeping all the routes together is better. For example, your NodeJS project may be an API and you can easily see all the endpoints served. This isn't breaking DDD. But here's how you can keep it lean:

# routes.js

const express = require('express');
const bodyParser = require('body-parser');
const { feature } = require('./router-utils');

const router = express.Router();

router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));


// Easy to see the route and what feature controls it.
router.get('/api/foo/bar/:something', feature('foo/bar'));
router.get('/api/foo/baz/:something', feature('foo/baz'));
router.get('/api/blah/blaaaah/:something', feature('blah/whatever'));


module.exports = router;
# router-utils.js

const cookie = require('cookie');
const auth = require('../auth/authorization');

const feature = (name, data = {}) => async (request, response, next) => {
  // Do middleware stuff with cookies
  const cookies = cookie.parse(request.headers.cookie || '');

  // Do middleware stuff with payloads
  if (request.url.includes('/some/path/here') && request.body?.payload) {
    request.body = JSON.parse(request.body?.payload);
  }
  const { something } = request.body || '';

  // Exit and continue to next routes if something is wrong.
  if (something_wrong_here) {
    next();
    return null;
  }

  const Feature = require(`../features/${name}/${name.split('/').pop()}`);

  // Pass all data to the feature.
  return new Feature({ request, response, next, data }).handle();
};

module.exports = { feature };
# /features/foo/bar.js

const Query = require('../../common/query');

class Bar extends Query {
  constructor(props) {
    // Attach the request object to "this.request"
    super(props);
  }

  async handle() {
    let response = {};

    const something = this.request.query.something;

    // make some REST call to an upstream service and return the response.
    // or make some database call and return the response.

}

module.exports = Bar;

2 Comments

So routes would be considered a domain ? Would it be good practice to create specific domain folders , with their routes on each domain ? Without a specific folder for routes?
Routing is outside of the domain folders. The domain folders don't care how you route to them. In the above, you see I have all the routes together and they call the domain-folder/feature: ie. foo/bar
1

An even simpler approach, just using the abilities of Node/js:

Say you have this:

app.use('/auth', async function (req, res, next) {
    .. code
    .. code
    .. code
    .. code
    .. code
    .. code
})

Recall you can simply do this:

app.use('/auth', someFile.someFunction {

I find this to be a very easy and clean approach. It's arguably better to have all the actual routes together in one place to look at. It may be useful in some projects.

2 Comments

Check out my answer on how I like to take this approach even further. :-)
very interesting. i will post a thing we do like this in a bit ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.