Brandon
Brandon

Reputation: 891

Creating a Modular REST API in ExpressJS

I'm having some trouble creating a RESTful API in Node/Express. In the app I'm building, a user has many messages, and messages belong to users. I need to be able to make an HTTP requests to retrieve all messages by a particular user. Here's the basic structure of the app, starting with the basic server, which delegates routing to a file called 'config/middleware.js'.

//server.js

var express = require('express');
var bodyParser = require('body-parser');

var app = express();

require('./config/middleware.js')(app, express);

var port = process.env.PORT || 8080;

app.use(bodyParser.json());
app.use(express.static(__dirname + '/../client'));

app.listen(port);

This is the middleware file where we send requests to the appropriate router. A request made to 'users/5/messages' would get routed to the messages router, and a request made to 'users/5' would get routed to the users router.

// config/middleware.js

module.exports = function(app, express) {
  var usersRouter = express.Router();
  var messagesRouter = express.Router();

  app.use('/users/:userId/messages', messagesRouter);
  app.use('/users', usersRouter);

  require('../routers/users')(usersRouter);
  require('../routers/messages')(messagesRouter);
};

This is the messages router. If a get request is made to '/users/5/messages', I want the getAllMessages function to be run, which should return all messages by the user with userId 5.

// routers/messages.js

var messagesController = require('../controllers/messages');

module.exports = function(app) {
  app.get('/:messageId', messagesController.getMessage);
  app.get('/', messagesController.getAllMessages);
};

The problem is that the getAllMessages function doesn't have access to the 'userId' parameter (with value of 5), which is required in order to make an appropriate query to the database. The getAllMessages function in the controller expects the userId to be stored on req.params.userId. Is there any way to get the userId of 5 to be present on the req.params object inside the getAllMessages function?

Upvotes: 1

Views: 1173

Answers (3)

Ankur Loriya
Ankur Loriya

Reputation: 3534

I was looking for same. Here is modules app example on github and auther site

Also we can change or update structure base on our requirements

Upvotes: 0

Bican
Bican

Reputation: 36

You can use app.locals or res.locals to pass some datas.

There is a good explanation about locals.

An usage sample:

app.locals.userid = req.params.userId; //binding userid

app.locals.userid // => '5'

OR: put a global variable.

user_id_tmp = req.params.userId;

Now this is become global variable in app. So you can call user_id_tmp variable from anywhere.

Upvotes: 0

Swaraj Giri
Swaraj Giri

Reputation: 4037

The req.params are not passed down the route chain. To do so, you could do something like

In server.js, create a key on req. This will pass on your data between routes. Do this before mounting the routes.

app.use(function (req, res, next) {
  req._data = {};

  next();
});

In config/middleware.js,

    module.exports = function(app, express) {
  var usersRouter = express.Router();
  var messagesRouter = express.Router();

  // attach usedId
  app.use('/users/:userId/messages', function (req, res, next) {
        req._data.userId = req.params.userId;
        next();
  });

  // mount the router
  app.use('/users/:userId/messages', messagesRouter);
  app.use('/users', usersRouter);

  require('../routers/users')(usersRouter);
  require('../routers/messages')(messagesRouter);
};

This way, you would have access to req._data.userId in routers/messages.js.

Side note: A better way to structure the routes would be to use something like, (read shameless plug), https://github.com/swarajgiri/express-bootstrap/blob/master/web/routes.js

Upvotes: 1

Related Questions