1

I've created a node application with express. I try to separate the following layers which will give me the ability to test the application with unit testing...

The problem is that I don't know how to call to the router.js file which will stops in the post/get/delete application.

The server.js file looks as follows

http = require('http'),
app = require('./app')(),
http.createServer(app).listen(app.get('port'), function (err) {
    console.log('Express server listening on port ' + app.get('port'));
});

This is the app.js file

var express = require('express'),
logger = require('morgan'),
bodyParser = require('body-parser'),
routesApp = require('./ro/route');

module.exports = function () {
    var app = express();
    app.set('port', process.env.PORT || 3005);

    app.use(logger('dev'));
    app.use(function (req, res, next) {
        res.set('APP', 'User app');
        next();
    });
    app.use(bodyParser.json());
    app.use(routesApp);
    return app;
};

This is the router.js, which will route the call to other module according to the http type like post/delete/get etc...

var handleGet = require('../controller/handleGet');
var handlePost = require('../controller/handlePost');
var express = require('express');

    module.exports = function (app) {

        var appRoute = express.Router();
        app.use(appRoute);
        appRoute.route('*')
            .post(function (req, res) {
                handlePost(req, res);
            })
            .get(function (req, res) {
                handleGet(req, res)
            })

Currently I've two questions:

  1. How to make it work since when in debug It dump in app.use(appRoute); on the router.js file? The error is TypeError: undefined is not a function

  2. Is it good way to structure the node app like in my post? I want to seperate all this layers like SOC, I'm fairly new to node and express and I try to build it to be modular and testable...

Simon Groenewolt
  • 10,607
  • 1
  • 36
  • 64
John Jerrby
  • 1,683
  • 7
  • 31
  • 68

1 Answers1

3
  1. How to make it work since when in debug It dump in app.use(appRoute); on the router.js file? The error is TypeError: undefined is not a function

This fails because you don't pass app into the module when you require it in app.js, you would need to do something like

app.use(routesApp(app)); // <- this hurts my eyes :(
  1. Is it good way to structure the node app like in my post?I want to sperate all this leyrs like SOC,I fairly new to node and express and I try to build it to be modular and testable...

Your definitely on the right track, keeping things separated is generally always a good idea. Testing is definitely one of the big pluses but it also helps with other things like maintainability & debugging.

Personally, I would make use of the bin directory for any start up script configuration

bin/www

var app = require('./app');
app.set('port', process.env.PORT || 3005);
var server = app.listen(app.get('port'), function() {
    console.log('Express server listening on port ' + app.get('port'));
});

This will help decouple your express app from all the environment setup. This should keep your app.js clean and only contain app-related config

app.js

var express = require('express')
  , app = express()
  , logger = require('morgan')
  , bodyParser = require('body-parser')
  , routes = require('./routes.js');

app.use(logger('dev'));
app.use(function (req, res, next) {
    res.set('APP', 'User app');
    next();
});
app.use(bodyParser.json());
app.use('/', routes);
...
module.exports = app;

Then finally, your routes.js should do nothing but handle your URLs

routes.js

var express = require('express')
  , router = express.Router()
  , handleGet = require('../controller/handleGet')
  , handlePost = require('../controller/handlePost');

router.get('/', handleGet);
router.post('/', handlePost);
...
module.exports = router;
James
  • 80,725
  • 18
  • 167
  • 237
  • Thanks James ! 1+, how to pass the request response to the post and get module from the router ? 2. In the server.js I define http server, I dont need it ? – John Jerrby Aug 08 '15 at 14:09
  • @JohnJerrby my example already demonstrates how you handle `get`/`post` responses from the router? No, express already does all this behind the scenes (again, see example). – James Aug 08 '15 at 14:11
  • Thanks but I put the function like following handlePost(req, res)) and I get error req is not defined...I need to pass it to handlePost and handleGet.. – John Jerrby Aug 08 '15 at 14:15
  • @JohnJerrby any function that has a signature of `function name(req, res) { ... }` can be passed as a handler for an express route. If you put in custom handlers i.e. `get('/', function(req, res) { handleGet(req, res); })` I presume that works? – James Aug 08 '15 at 14:21
  • Ok Its not working , can you please update the post how to pass this params since maybe I miss something...Thanks! – John Jerrby Aug 08 '15 at 14:25
  • @JohnJerrby you need to be more specific, what isn't working? Your routes aren't working at all or they just aren't mapping to the custom `handleGet` / `handleSet` methods? Unfortunately since this is custom code outwith the scope of the question I will find it difficult to diagnose why those aren't working... – James Aug 08 '15 at 14:27
  • Ok I try to handle it bymyself :) last question can you please elborate on the server.js ,why you put it on the bin folder and not in the root and which benefit you got from it ? and how should I invoke it to start my node application ?Thanks sir! – John Jerrby Aug 08 '15 at 14:37
  • @JohnJerrby see this [question](http://stackoverflow.com/questions/23169941/what-does-bin-www-do-in-express-4-x) :) – James Aug 08 '15 at 14:39