cnak2
cnak2

Reputation: 1841

Modularize my Express/Mongoose API code to make it easier to work with

I'm new to creating APIs with Express and Mongoose.

I currently set up CRUD end points for a Guestbook collection.

I want to setup CRUD for three or for more collections (e.g Users, Posts, Products, etc.)

What I'd like to know is if there is a way to separate each of these into individual router files so I don't have one very long page of CRUD calls for each collections.

Here is what my API page looks like:

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


//GUESTBOOK END POINTS
var Guestbook = require('../models/guestbook')

router.route('/guestbook')

.post(function(req, res) {

    var guestbook = new Guestbook();

    guestbook.firstname = req.body.firstname;
    guestbook.lastname = req.body.lastname;
    guestbook.email = req.body.email;
    guestbook.postedon = req.body.postedon;
    guestbook.comment = req.body.comment;
    guestbook.rate = req.body.rate;

    guestbook.save(function(err) {
        if (err)
            res.send(err);

        res.json({ message: 'Post created!' })

    });

})

.get(function(req, res) {
    Guestbook.find(function(err, guestbook) {
        if (err)
            res.send(err);

        res.json(guestbook);
    });

});


router.route('/guestbook/:id')

.get(function(req, res) {

    Guestbook.findById(req.params.id, function(err, guestbook) {
        if (err)
            res.send(err);

        res.json(guestbook);

    });

})

.put(function(req, res) {

    Guestbook.findById(req.params.id, function(err, guestbook) {

        if (err)
            res.send(err);

        //USING OBJECT.KEYS TO UPDATE ONLY PARAMS PASSED
        Object.keys(req.body).forEach(function(prop) {
            if (typeof req.body[prop] !== 'undefined') {
                guestbook[prop] = req.body[prop];
            }
        });

        guestbook.save(function(err) {

            if (err)
                res.send(err);

            res.json(guestbook);

        });

    });

})

.delete(function(req, res) {

    Guestbook.remove({ _id: req.params.id }, function(err, guestbook) {
        if (err)
            res.send(err);
        res.json({ message: 'Successfully deleted!' });
    });

});


//RETURN ROUTER AS MODULE
module.exports = router;

Upvotes: 1

Views: 93

Answers (1)

Ryan Walsh
Ryan Walsh

Reputation: 40

The way I do this is by separating out my code by feature in a structure that looks similar to this:

index.js
features/
-- user/
---- User.js
---- userRoutes.js
---- userCtrl.js

So your code could look something like this:

var express = require( "express" );
var router = express.Router();
var guestbookRoutes = require( "./guestbookRoutes" );

guestbookRoutes( router );

module.exports = router;

Then in guestbookRoutes

var guestbookCtrl = require( "./guestbookCtrl" );

module.exports = function( router ) {
    router.route( "/guestbook" )
        .post( guestbookCtrl.postBook );

    /* the rest of your routes */
}

And finally in guestbookCtrl.js you would have your handler functions in an object.

module.exports = {
    postBook: function(req, res) {

      var guestbook = new Guestbook();

      guestbook.firstname = req.body.firstname;
      guestbook.lastname = req.body.lastname;
      guestbook.email = req.body.email;
      guestbook.postedon = req.body.postedon;
      guestbook.comment = req.body.comment;
      guestbook.rate = req.body.rate;

      guestbook.save(function(err) {
          if (err)
              res.send(err);

          res.json({ message: 'Post created!' })
         });  
      }
    }
    /* the rest of your handler functions */

This allows you to separate out the code into neat component directories with a focused purpose. Hopefully this helps!

Upvotes: 1

Related Questions