A JS ORM for nodejs / mongo-db and/or the browser.
RestMongo works by letting you describe your data using a JSON schema and then provides you high level objects which can be created / updated / deleted / retrieved using an easy-to-use API. The core functionalities work on both node and the browser. There are different backends, wether you want to plug to a mongodb, a REST API, etc.
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"}
}
},
methods: {
sayHello: function() {
console.log("Hello, "+ this.firstname);
}
}
}
};
The schema describes a document. It can have references or list of references to other documents. You can also associate methods to objects in the schema. Here, we will have the sayHello method available on Person objects.
var rest_mongo = require("rest-mongo");
var mongo_backend = require('rest-mongo/mongo_backend');
var backend = mongo_backend.get_backend({db_name: 'db_name', username: "username", password:"password"});
var RFactory = rest_mongo.getRFactory(schema, backend);
var R = RFactory();
Get a new R every time you need to get a new context to work in (at every client request for example).
When creating a RFactory, you can specify an additional schema that will extend the base one. This is done so you can have properties or methods specific to server/browser side.
var server_schema = {
"Person": {
schema: {
properties: {
secret: {type: "string"}
}
},
methods: {
get_same_secrets: function(callback, fallback) {
// Returns Persons with the same secret as me.
this.R.Person.index({query: {secret: this.secret}},
callback, fallback);
}
}
}
}
var RFactory = rest_mongo.getRFactory(schema, backend, {
additional_schema: server_schema
});
var lilly = new R.Person({firstname: "Lilly"});
lilly.sayHello();
lilly.save(function() {
sys.puts("Lilly saved in DB with id " + lilly.id());
});
R.Person.get({
ids: lilly.id()
}, function(lilly2){
// lilly and lilly2 are the same
});
R.Person.index({
query: {firstname: "Lilly"}
}, function(data){
var lilly = data[0];
});
lilly.delete_(function(){
sys.puts('Lilly deleted from DB!');
}, function() {
sys.puts('You can not delete Lily!');
});
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.');
});
R.Person.update({
ids: [lilly.id(), harry.id()],
data: {firstname: 'anonymous'}
}, function() {
sys.puts("Voldemort cannot find them anymore...");
});
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);
});
R.Person.remove({
firstname: 'anonymous'
}, function() {
console.log('There is no more anonymous person in DB.');
});
R.Person.remove({}, function() {
console.log('No more person object in DB.');
}, function(error) {
console.error('Could not remove all persons from DB.');
});
rest-mongo also provides you with a connect middleware which can serve your data over a REST API using the provided schema.
var connector = rest_server.connector(RFactory, schema);
server = http.createServer(function(req, resp) {
connector(req, resp, function() {
res.writeHead(404, {}); res.end();
});
});
server.listen(8888);
If is now possible to get the list of Person objects doing a GET HTTP request on localhost:8888/people
It is possible to specify a third argument auth_check when calling the connector function. This argument should be a function. If provided, it will be called to check if rest-mongo can reply to the request or not. The function signature is:
auth_check(req, res, next, info)
- req: nodejs req obj.
- res: nodejs res obj.
- next: to be called if ok to continue serving the request.
- info: hash containing 'pathname', 'method', and 'data' attrs.
This version has been tested on:
- node (v0.3.0)
- node-mongodb-native
- mongodb (1.6.1 and 1.4.2)
- nodetk
node-mongodb-native and nodetk are vendorized through git submodules:
$ git submodule update --init
To run the tests: nodetests
Please have a look at the nodetk README file to install nodetk.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.fsf.org/licensing/licenses/agpl-3.0.html