Refactoring
This code in the entry point main.js in the former post is a bit verbose. If an application becomes more complex you don't really want to put all your logic in one file. Best practice is to keep thing small, by making every program a proxy.
Disclaimer: my blog posts may not be best practice for everybody in every situation. The code I share however works for me and gets the job done. I strive to keep everything as simple as possibe.
Model, View, Controller
In this post we will create a Model and a Controller (no Views because this is still just a REST API without a frontend).
Finally we'll create the routes.
The main.js file requires the routes, the routes require the controller, the controller requires the model.
Yep, that should do.
Create a model
So let's clean out the mess. Create a new folder named 'app'. From the main.js file we will put the 'Food' model into a separate file.
I will save the file as model.food.js.
var mongoose = require('mongoose'), Schema = mongoose.Schema; var FoodSchema = new Schema({ name: String, description: String, price: String }); mongoose.model('Food', FoodSchema); module.exports = mongoose.model('Food');
'Module.exports' wraps everything so that later on you can "require" this module and use the "new" operator to create a new instance of the Food object type, which is done in the controller in the next paragraph.
Create a controller
I put the CRUD into a controller (per this example).
I will save the file as controller.food.js
Notice how I 'require' the Model in the first line.
var Food = require('./model.food.js'); exports.create = function (req, res) { var food = new Food(req.body); console.log(food); food.save(function (err) { if (err) { return res.send({ message: err }); } else { res.send({ success: true, food: food }); } }); }; exports.list = function (req, res) { Food.find(function (err, data) { if (err) { res.send(err); } res.json({ success: true, food: data }); }); }; exports.findOne = function (req, res) { Food.findOne({ _id: req.params.id }, function (error, response) { if (error) { res.send(error); } else { res.send({ success: true, food: response }); } }); }; exports.findByName = function (req, res) { Food.findOne({ name: req.params.name }, function (error, response) { if (error || !response) { res.status(404).send({ status: 401, message: 'not found' }); } else { res.send({ success: true, food: response }); } }); }
Here I am basically wrapping methods around the Food object, using exports.methodname.
In case you are wondering (I was, and have to admit still am wondering about this sometimes), this article explains the difference between 'module.exports' and 'exports' as follows: 'module.exports' is the real deal, exports is just its little helper. For now, I am OK with that. Let's just get things done already. π
Separate the routes
Here the controller.food.js file is required.
I will save the file as routes.food.js.
//mongodb var foodstuff = require('./controller.food'); module.exports = function (app) { app.route('/food').post(foodstuff.create); app.route('/food').get(foodstuff.list); app.route('/food/:id').get(foodstuff.findOne); app.route('/foodname/:name').get(foodstuff.findByName); };
Well then, we're done. Now let's give main.js a haircut.
Refactor main.js
So, we now have a small and clean main.js file.
var express = require('express'); var app = express(); var bodyparser = require('body-parser'); var mongoose = require('mongoose'); app.use(bodyparser.urlencoded({ extended: true })); app.use(bodyparser.json()); mongoose.connect('mongodb://localhost:27017/restaurant'); require('./app/routes.food')(app); app.use(express.static(__dirname + '/public')); app.set('port', process.env.PORT || 3001); app.listen(app.get('port')); console.log("the server is running on http://localhost:" + app.get('port'));
If you followed along, the directory structure looks like this:
.
βββ app
βΒ Β βββ controller.food.js
βΒ Β βββ model.food.js
βΒ Β βββ routes.food.js
βββ main.js
βββ node_modules
βΒ Β βββ body-parser
βΒ Β βββ express
βΒ Β βββ mongoose
βββ package.json
βββ public
βββ index.html
What's next?
Next up is authentication testing.
2 thoughts on “Beginning Node.js – REST API with a Mongodb backend (refactoring) – part 4”