TheLovelySausage
TheLovelySausage

Reputation: 4094

NodeJS Express defining custom routes

This is probably a really basic concept that I'm not understanding but in my NodeJS application I am trying to define a custom route.

my directory structure is as follows

/application
    /app.js
    /package.json
    /node_modules
    /public
    /routes
        /control
            /users.js
    /views
        /control
            /users.ejs

Which I am happy with because I want to keep the routes and views in a 1 to 1 relationship because I will eventually end up with something like

/application
    /app.js
    /package.json
    /node_modules
    /public
    /routes
        /control
            /users.js
            /system.js
        /tools
            /stock.js
            /report.js
    /views
        /control
            /users.ejs
            /system.ejs
        /tools
            /stock.ejs
            /report.ejs

So I don't want to end up with a /routes/index.js file with a hideous amount of routing code inside.

It seems to work while my app.js file is as follows

//==============================================================================
// setup
//==============================================================================

var express = require("express");
var path = require("path");

var app = express();
var port = 3000;
var message = null;

app.set("view engine", "ejs");

app.use(express.static(path.join(__dirname, "public")));

//==============================================================================
// routes
//==============================================================================

var users = require("./routes/control/users");
app.get("/", users.users);

//==============================================================================
// start server
//==============================================================================

app.listen(port, function() {

   message = "Server Started : Port " + port;
   console.log(message);

});

Although I can see this is going to end up looking like

//==============================================================================
// setup
//==============================================================================

var express = require("express");
var path = require("path");

var app = express();
var port = 3000;
var message = null;

app.set("view engine", "ejs");

app.use(express.static(path.join(__dirname, "public")));

//==============================================================================
// routes
//==============================================================================

// control

var users = require("./routes/control/users");
app.get("/", users.users);

var system = require("./routes/control/system");
app.get("/", system.system);

// tools

var stock = require("./routes/tools/stock");
app.get("/", stock.stock);

var report = require("./routes/tools/report");
app.get("/", report.report);

//==============================================================================
// start server
//==============================================================================

app.listen(port, function() {

   message = "Server Started : Port " + port;
   console.log(message);

});

So I don't really want to have that many requires but doing it like the following doesn't seem to work and I'm not sure why

// control

var control = require("./routes/control");

app.get("/", control.users.users);
app.get("/", control.system.system);

// tools

var tools = require("./routes/tools");

app.get("/", tools.stock.stock);
app.get("/", tools.report.report);

Upvotes: 2

Views: 4039

Answers (2)

Brian
Brian

Reputation: 1893

You can use the express Router object to chain your routes. Here's an example

/app.js

var routes = require('./routes/index');

// as noted by Paul in the comments, 
// you could use `app.use(routes)` for simplicity
app.use('/', routes);

/routes/index.js

var routes = require('express').Router();

routes.route('/test')
    .get(function (req, res) {
        res.send(req.originalUrl);
    });

routes.use('/control', require('./control/user'));

module.exports = routes;

/routes/control/user.js

var routes = require('express').Router();

routes.route('/test')
    .get(function (req, res) {
        res.send(req.originalUrl);
    });

module.exports = routes;

So for the route defined in index.js, you'll need to send a GET request to /test while in user.js, you will need to send a GET request to /control/test to get a response.

This way all you need to include in the main js file, app.js in your case, is the main routes file, which is index.js under the routes directory. Either way, you will still need to do one require statement for each file that exports a router object.

Upvotes: 6

dNitro
dNitro

Reputation: 5345

When you say:

var control = require("./routes/control");

Node will do the followings:

  1. Since you privided a relative path to require, it will search for a routes directory within the current folder and in that directory search for a control.js file. It can't find control.js file so then:
  2. Search for a control.json file. but it also can't find that file. then:
  3. Search for a control directory. It finds such a directory. opens it and search for a package.json file to look into its main property. but it also cant find such a file. then:
  4. Search for a index.js file but also there is no such a file

By default when you give a folder path to require, it does not load .js files inside that folder automatically it looks for package.json file and if it's not there it loads index.js. i. e. It looks for an entry point.

So make an index.js in your control folder:

/routes
  /control
    /users.js
    /system.js
    /index.js

index.js:

module.exports = {
  users: require('./users');
  system: require('./system');
};

Do this also for your tools directory and your last approach should work.

Note that you could consider using express.Router to manage routes.

Upvotes: 3

Related Questions