livegoose
v1.0.1
Published
declarative api building with mongoose
Downloads
4
Maintainers
Readme
WIP
This is still an early wip. It has not yet been tested as thoroughly as I would like, but appears to be working for everything except the populate methods on the routes. If anyone has the courage to be an early adopter I welcome the feedback.
LiveGoose
Livegoose is very lightweight module which allows for extremely declarative rest programming with mongoose backends. Livegoose is built on top of the preston module, which supplies most of the functionality. Livegoose simply allows the process to be more declarative.
All the user needs to do is to create a folder (./models by default, but configurable) which contains a file for each mongoose schema/model (see the models section for details). Then with a minimal amount of setup mongoose is off and running.
Setup
Set up for livegoose is extremely simple. The user simply requires livegoose and then passes in a mongoose instance. The user is then returned a livegoose object which can be configured by modifying the values for models and/or url. Then simply call the render function and pass in the app object created from express to enable your routes.
Example:
#LiveScript
#setup
require! livegoose
require! mongoose
mongoose.connect = 'localhost:..'
goose = livegoose mongoose #pass in a mongoose instance
#optional configuration
goose.models = "#{__dirname}/myfolder" #default "#{process.cwd()/models}"
goose.url = '/api' # defualt '/'
#usage
app = express!
#app setup
goose.render app #goose.render returns the app so it can be chained
// JavaScript
// setup
var livegoose, mongoose, goose, app;
livegoose = require('livegoose');
mongoose = require('mongoose');
mongoose.connect = 'localhost:..';
goose = livegoose(mongoose);
// optional configuration
goose.models = __dirname + "/myfolder"; //default process.cwd() + "/models"
goose.url = '/api';
//usage
app = express();
goose.render(app);
Models
Each file in the livegoose.models folder (default './models') returns a single object. From this object livegoose will build your schemas, models, routes and subroutes.
These objects have two required fields:
name: which will the name of the model and, if the model will be a route, serve as the basis for the name of the route (routes are converted to lowercase-plural)
name: 'MyModel' #model = 'MyModel', route 'mymodels' (if generated)
schema: this is simply a mongoose schema
schema: firstName: String lastName: String dob: Date
Additionally, there are several optional fields that can be set.
pre: If pre is set, pre itself is an object which can be used to set pre-hooks on the schema. Currently mongoose supports pre-hooks for save, remove, and validate. All pre-hooks are given a next function from mongoose which needs to be called on the conclusion of the user's function.
pre: save: (next) !-> console.log 'saving object' next! remove: (next) !-> console.log 'removing object' next! validate: (next) !-> console.log 'validating' next!
post: Similar to pre, but defines post hooks. Post-hooks also have save, remove and validate options. Post-hooks are not given a next function and do not need to call anything on completion.
post: save: !-> console.log 'object saved' remove: !-> console.log 'object removed' validate: !-> console.log 'validated'
index: This field is an array of objects used to set indices that are not set on the schemas. This is especially useful for multi-field indices or coding styles that prefer to set all indices in one location.
index: * lastName: 1 firstName: 1 ...
route: If the route field is set to false or not set, the model will be created but will not be a standalone route. This allows models to be created which will be sub-routes for another route and not routes themselves. If route is set to true, the model will be turned into a standalone route (i.e. no sub-routes). If route is set to an object, each sub-object will be used to create a sub-route. Route names will be determined by the name field in the object, converted to lowercase-plural. Sub-route names are determined by the keys of the route object.
# standalone route route: true # route with sub-routes route: emails: #key defines how you want the subroute to be called from the client ref: \clientId #the attibute from the model which references the main model model: \email #the name of the model as defined in the name key of your object macros: ref: \client model: \clientMacro
cascade: If cascade is set to true. Livegoose will automatically generate a pre-remove hook which removes all documents in the sub-routes whose 'ref' field matches the _id of the document being removed.
cascade: true
Mongoose Connections
When you require livegoose you are given a function. This function only returns the livegoose object when it is passed a mongoose instance. This allows users to create different livegoose models for different mongoose connections. For example.
#LiveScript
firstconn = mongoose.createConnection "..."
secondconn = mongoose.createConnection "different ..."
firstgoose = livegoose firstconn
secondgoose = livegoose secondconn
firstgoose.models = "./firstmodels"
firstgoose.url = "/firstapi"
secondgoose.models = "./secondmodel"
secondgoose.url = "/secondapi"
#some time later after app creation
firstgoose.render app
secondgoose.render app
// JavaScript
var firstconn, secondconn, firstgoose, secondgoose;
firstconn = mongoose.createConnection("...");
secondconn = mongoose.createConnection("different ...");
firstgoose = livegoose(firstconn);
secondgoose = livegoose(secondconn);
firstgoose.models = "./firstmodels";
firstgoose.url = "/firstapi";
secondgoose.models = "./secondmodel";
secondgoose.url = "/secondapi";
// some time later after app creation
firstgoose.render(app);
secondgoose.render(app);
Another advantage to setting up livegoose this way is that a user could choose to use a mongoose fork, or similar module, as long as it contained the same api, and livegoose will work correctly.