828
828

Reputation: 1180

How do I design my Node.js API so that I can also consume it from the server side?

I have an API that returns some JSON from mongodb:

// In router.js
var api = require('api') 
app.get('/lists', api.lists);

// In api.js
var db = require('db')
exports.lists = function(req, res) {
  db.lists.find({}, function(err, lists) {
    res.send(lists);
  });
};

Is there a way to design the API so that I could also consume it from within my Node.js app? I'm trying to avoid having to duplicate any of the database code outside the API. I basically have a controller that can render the data server-side:

// In controller.js
var api = require('api')
exports.page = function(req, res) {
  res.send(api.lists()); // This won't work
};

I found a hacky solution which was to pass a callback function to the api.lists(), but I have a feeling this is the "wrong" way to achieve this:

// In api.js
exports.lists = function(req, res, callback) {
  db.lists.find({}, function(err, lists) {
    if(callback){
       callback(lists);
    } else {
       res.send(lists);
    }
  });
};

Any ideas?

Upvotes: 0

Views: 412

Answers (1)

Hector Correa
Hector Correa

Reputation: 26690

I think the problem is that in your current code you are coupling your API to the response object. You can decouple them with something like this:

In router.js instead of using api.lists as the callback, define a function that will call api.lists with a callback that is wired to the response object. In this case api.list DOES NOT need to know about the response object but the function that we are creating does.

// In router.js
var api = require('api');
app.get('/lists', function(req, res) {
  api.lists(function(err, lists) {
    if(err) {
      res.send('error page');
      return;
    }
    res.send(lists);
  });
});

In api.js we remove the reference to the response object. Now it will just call whatever callback it received with the appropriate data (err + lists). It's up to the callback to do whatever it pleases with the result.

// In api.js
var db = require('db')
exports.lists = function(callback) {
  db.lists.find({}, function(err, lists) {
    callback(err, lists);
  });
};

Upvotes: 3

Related Questions