af83

Rest-mongo

Rest-mongo is a javascript library for NodeJS and the browser. On the node's side it features an ORM in front of a Mongo DB. On the client's side, it features the same ORM but with a REST API backend. The server-side part can also expose the REST API needed by the client (but there is no notion of authorizations yet). It works by specifying a JS schema of your data (schema that can be shared by both your client and server code). Here is an example of schema:

var schema = {
  "Person": {
    resource: "/people",
    schema: {
      id: "Person",
      description: "someone, blablabla",
      type: "object",
       
      properties: {
        firstname: {type: "string"},
        friends: {type: "array", items: {"$ref": "Person"}},
        mother: {"$ref": "Person"}
      }
    }
  }
};

Here we have described a Person that has the following properties:

  • firstname, string;
  • friends, list of references to other persons;
  • mother: reference to another Person.

The "resource" property of the Person object is not mandatory, but is needed if you want to expose/use the REST API.

Once we have a schema describing our data, we need to get the "R" object (describing a unit of work). Get a new R every time you need to get a new context to work in (at every client request for example).

var rest_mongo = require("rest-mongo");
var RFactory = rest_mongo.getRFactory(schema, "db_name");
var R = RFactory();

Then we can start hacking around:

 // Create and save an object into the DB:
 var lilly = new R.Person({firstname: "Lilly"});
 lilly.save(function() {
   sys.puts("Lilly saved in DB with id " + lilly.id());
 });

 // Get one or more objects from DB:
 R.Person.get({
   ids: lilly.id()
 }, function(lilly2){
  // lilly and lilly2 are the same
 });

 // Search in DB:
 R.Person.index({
   query: {firstname: "Lilly"}
 }, function(data){
   var lilly = data[0];
 });

 // Delete an object:
 lilly.delete_(function(){
   sys.puts('Lilly deleted from DB!');
 }, function(err) { // the 2nd callback is a fallback (not mandatory)
   sys.puts('You can not delete Lily!');
 });

 // Usage of references:
 var harry = new R.Person({firstname: "Harry", mother: lilly});
 harry.save(function() {
   sys.puts('Only the id of Lilly has been saved in harry.mother in DB.');
 });

 // Update more than one field in once:
 R.Person.update({
   ids: [lilly.id(), harry.id()], 
   data: {firstname: 'anonymous'}
 }, function() {
   sys.puts("Voldemort cannot find them anymore...");
 });

 // Save more than one object in once:
 var p1 = new R.Person({firstname: 'Hermione'});
 var p2 = new R.Person({firstname: 'Ron'});
 R.save([p1, p2], function() {
   console.log('Now Harry has friends.')
 }, function(error) {
   console.log('Harry has no friends, because of ', error);
 });
 

Of course the project is lacking a lot of features that could be interesting to have, but it's well documented and tested, so don't hesitate to hack on it. It has been tested and works fine on node v0.1.100, we should soon update it for node 0.2.0.

It uses node-mongodb-native to connect to mongoDB and nodetk for orchestration, tests and other miscellaneous tools. It has been used to build Geeks, a fun events based {office, place, …} map to locate people (and eventually do a lot of other things).

Have fun and don't hesitate to comment,
Pierre

Rest-mongo on GitHub: http://github.com/AF83/rest-mongo.

blog comments powered by Disqus