Anatomy of an OAE backend module - Orodan/Hilary GitHub Wiki

An OAE backend module is a regular node.js module.

Structure

It should have the following structure:

oae-mymodule
 ├── README.md
 ├── package.json
 ├── lib
 │   ├── init.js
 │   ├── api.js
 │   ├── model.js
 │   ├── rest.js
 │   └── internal
 │       └── dao.js
 └── tests

package.json

Contains the metadata that is pertinent to your module and will be used by node/npm to resolve files in your module

{
    "name": "oae-doc",
    "version": "0.0.1",
    "main": "./lib/api.js"
}

The main key should point to the file that will expose any logic you wish to export. Typically other modules should only require this file.

The lib folder

Contains all the code that is required for your module to function.

lib/init.js

This file exports object should be replaced with a function. This function will get called on server start-up and will allow you to do any initialization or bootstrapping that your module might require. Things like creating Cassandra column families, caching files, setting up sockets with a remote server, ... Once you're done, you should call the callback, so the server can continue bootstrapping other modules e.g.: var MyAPI = require('./api');

module.exports = function(config, callback) { // Cache Stuff MyAPI.init(config, callback); };

lib/model.js

Contains the models that your module might expose. These models are used when retrieving data from cassandra and passing them around between node.js modules and/or too the REST apis. e.g.:

var User = function(id, displayName) {
    var that = {};
    that.id = id;
    that.displayName = displayName;
    return that;
};

lib/api.js

Contains all the business logic for your module.

var MyDAO = require('./internal/dao');

var getSomeDataById = module.exports.getSomeDataById = function(id) { 
    // Get the data from Cassandra via the DAO (see below)
    MyDAO.getSomeDataById(id, function(err, data) {
        if (err) {
            return callback(err);
        }

        // Do something else with data
        // ..


        return callback(null, data);
};

lib/rest.js

If your module wishes to expose REST endpoints it can do so here. The expressjs server objects are exposed on the oae-util/lib/oae module. It will export a tenantRouter where endpoints can be added that should be exposed for tenants and the globalAdminRouter for endpoints that are only required on the global admin site.

Typically, you would limit the amount of code that goes into this file and call down to exported functions from your API.

var OAE = require('oae-util/lib/oae');

var MyAPI = require('./api');

/*!
 * Return some data
 */
OAE.tenantRouter.on('get', '/api/mymodule/:id', function(req, res) {
    MyAPI.getSomeDataById(req.params.id, function(err, data) {
        if (err) {
            return res.send(err.code, err.msg);
        }
        res.send(200, data);
    });
});

lib/internal

Contains the code that no other module should call (unless they really know what they are doing). Think of this as your internal implementation logic.

lib/internal/dao.js

Contains the code that takes care of persisting to and/or retrieving data from Cassandra/Redis. There is a utility available at oae-util/lib/cassandra which allows you to execute a query, run multiple batch queries, generate upsert queries, etc..