Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express: Separate route and controller files

I'm trying to split out some routes and their handler logic in Express in separate files. I have seen examples directory structures like on mean JS where separate route and controller files are used, so it's that approach I am trying to implement but am hitting an issue.

My server and routes are configured like so:

server.js

var express = require('express'),
  app = express(),
  bodyParser = require('body-parser'),
  routes = require('./routes/index')

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

/routes/index.js

module.exports = function(app) {
  var catalogues = require('../routes/catalogues');
  app.use('/catalogues-api', catalogues);
};

/routes/catalogues.js

var catalogues = require('../controllers/catalogues');
module.exports = function(app) {

  app.route('/catalogues')
    .get(catalogues.apiGET)
    .post(catalogues.apiPOST);
};

/controllers/catalogues.js

var request = require('request');

exports.apiGET = function(req, res) {
  var options = prepareCataloguesAPIHeaders(req);
  request(options, function(err, response, body){
    res.send(body);
  });
};

exports.apiPOST = function(req, res) {
  var options = prepareCataloguesAPIHeaders(req);
  options.json = true;
  options.body = stripBody(req.body);
  request(options, function(err, response, body){
    res.send(body);
  });
};

When running the application and a GET request is made against /catalogues-api/catalogues I get an error thrown from node:

TypeError: undefined is not a function at module.exports (C:\Users\rparker\Documents\GitHub\testproj\src\server\routes\catalogues.js:4:7)

This is referencing the app.route declaration in my /routes/catalogues.js file. I have obviously missed something in my setup but I cannot figure it out.

Can someone please assist? Thanks

like image 777
mindparse Avatar asked Dec 09 '15 08:12

mindparse


2 Answers

in /routes/catalogues.js

var express = require('express');
var router = express.Router();
var catalogues = require('../controllers/catalogues');

router.route('/catalogues')
.get(catalogues.apiGET)
.post(catalogues.apiPOST);
module.exports = router;

Check out the last part of this documentation

like image 149
ma08 Avatar answered Oct 16 '22 16:10

ma08


You may find a really nice autoloader in npm called 'require.all' that may help you a lot in automating the process of linking routes, controllers and models. At the end of the documentation is given similar example that assumes that all you route files export functions that expect controllers as parameter and return an express.Router object.

like image 24
Slim Avatar answered Oct 16 '22 16:10

Slim