Wednesday, April 15, 2015

Coding the REST services (Part 1) - The model

Coding up the REST services part is similar to coding up the CRUD parts for you traditional desktop application. The difference is quite subtle because you'll be also dealing with HTTP verbs - POST, GET, PUT, DELETE. We are going to make the data model first so we have something to interact with.

First step is creating a connection. In our case, we are connecting to MongoLab, so in your app.js file you add the following:

// our libs
var mongoose = require('mongoose');
var uriUtil = require('mongodb-uri');

// our connection function
var connectToMongoLab = function () {
    var username = process.env.MongolabUsername;     // external var for our username
    var password = process.env.MongoLabPassword;     // same for the password

    var mongolabUri = "mongodb://" + username + ":" + password + "@ds035448.mongolab.com:35448/dbhaxspace";
    var mongooseUri = uriUtil.formatMongoose(mongolabUri);
    var options = {
        server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
        replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
    };
    mongoose.connect(mongooseUri, options);  // connect us to the db with these options
};

connectToMongoLab(); 

mongoose.connection.on('error', console.log);   // if error in connecting to db, dump errmsg to console
mongoose.connection.on('disconnected', connectToMongoLab); // if disconnected just reconnect

// load models
fs.readdirSync(__dirname + "/models").forEach(function(file) {
    if (~file.indexOf('.js')) require(__dirname + '/models/' + file);
});

This should be added before the routes portions. Now for the actual model.

We're using Mongoose to model our data. Think Entity Framework if you're a C# guy, Hibernate (or JPA) if Java and SQLAlchemy for the python guys. (No, PHP gets not love. #Dealwithit)

Create a folder called Model and create a new javascript file in that folder. In our project, our model is called post and it's declared in the post.js file.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var PostSchema = new Schema({
    title: { type: String, default: '' },
    author: { type: String, default: '' },
    body: String,
    published: Boolean,
    date: { type: Date, default: Date.now },
    geoloc: {
        latitude: { type: Number, default: 0 },
        longitude: { type: Number, default: 0 },
        label: { type: String, default: ''} 
    },
    meta: {
        uvotes: { type: Number, default: 0 },
        dvotes: { type: Number, default: 0 },
        favs: { type: Number, default: 0 }
    }
});
// methods
PostSchema.method({
    findAll : function(cb) {
        return this.model('Post').find({}, cb);
    }  
});
// statics
PostSchema.static({

});
// register
mongoose.model('Post', PostSchema, 'posts');

Mongoose schema's have some pretty nifty features like types, methods and statics that can be part of the model. The whole thing then wraps up when you call the mongoose.model() function to register the model.

Once we have our model registered. We can then call our model into any part of the app.

var mongoose = require('mongoose');
// Get the model
var post = mongoose.model('Post');

We will pick this up on part 2 where I actually show you the REST parts.