mongodb-rest
Advanced tools
Comparing version 0.10.2 to 0.10.3
@@ -17,3 +17,4 @@ { | ||
"flavor": "nounderscore", | ||
"debug": true | ||
"debug": true, | ||
"humanReadableOutput": true | ||
} |
@@ -50,2 +50,3 @@ /* | ||
if (err) { | ||
db.close(); | ||
res.status(500).send(err.message); | ||
@@ -60,2 +61,3 @@ return; | ||
res.json(dbNames); | ||
db.close(); | ||
}); | ||
@@ -65,2 +67,34 @@ }); | ||
// | ||
// Get names of all collections in specified database. | ||
// | ||
app.get('/:db', function (req, res) { | ||
var db = new mongo.Db(req.params.db, new mongo.Server(config.db.host, config.db.port, serverParams), dbParams); | ||
db.open(function(err,db) { | ||
if (err) { | ||
db.close(); | ||
res.status(500).send(err.message); | ||
return; | ||
} | ||
db.collectionNames(function (err, collections) { | ||
if (err) { | ||
db.close(); | ||
res.status(500).send(err.message); | ||
return; | ||
} | ||
var collectionNames = collections.map(function (collection) { | ||
// Pull out the name of the collection and chop off the database name. | ||
return collection.name.substring(req.params.db.length+1); | ||
}); | ||
res.json(collectionNames); | ||
db.close(); | ||
}); | ||
}); | ||
}); | ||
/** | ||
@@ -67,0 +101,0 @@ * Query |
{ | ||
"name": "mongodb-rest", | ||
"description": "REST API Server for MongoDB", | ||
"version": "0.10.2", | ||
"version": "0.10.3", | ||
"author": "Ashley Davis <ashleydavis@insanefx.com>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
102
README.md
@@ -9,7 +9,10 @@ This project is no longer abandoned! | ||
Recent updates: | ||
mongodb-rest now works with dependencies updated to latest versions. | ||
Added handling for mongodb errors. | ||
Removed Jade dependency. | ||
Can now get a list of database names. | ||
Recent updates:<br/> | ||
mongodb-rest now works with dependencies updated to latest versions.<br/> | ||
Added handling for mongodb errors.<br/> | ||
Removed Jade dependency.<br/> | ||
Can now get a list of database names.<br/> | ||
Can now get a list of collection names for a specified database.<br/> | ||
It is now easier to start and configure the server procedurally.<br/> | ||
REST API output is now human readable by default.<br/> | ||
@@ -29,33 +32,77 @@ Name | ||
Installation is via npm: `npm install mongodb-rest`. | ||
You can install globally using -g: `npm install -g mongodb-rest`. | ||
Installation is via npm: | ||
> npm install mongodb-rest | ||
You can install globally using -g: | ||
> npm install -g mongodb-rest | ||
Now issue `mongodb-rest` on the command line and the server should start. | ||
NOTE: Make sure you are running a MongoDB database in addition to the `mongodb-rest` server. | ||
NOTE: Make sure you are running a MongoDB database in addition to the mongodb-rest server. | ||
Try | ||
--- | ||
Test | ||
---- | ||
After installation you can quickly test it by issuing the following from the command line: | ||
After installation you can quickly test it by issuing the following from the command line:<br/> | ||
> curl -d '{ "A1" : 201 }' -H "Content-Type: application/json" http://localhost:3000/test/example1 | ||
This should add a document to the "test" db.example1 collection: | ||
{ | ||
"A1": 201, | ||
"_id": ObjectId("4e90e196b0c7f4687000000e") | ||
} | ||
Notes | ||
----- | ||
{ | ||
"A1": 201, | ||
"_id": ObjectId("4e90e196b0c7f4687000000e") | ||
} | ||
Start Server Programmatically | ||
----------------------------- | ||
mongodb-rest can easily be started programmatically by 'requiring' the module and calling `startServer`. | ||
var mongodbRest = require('mongodb-rest'); | ||
mongodbRest.startServer(); | ||
You can optionally pass in a configuration object: | ||
mongodbRest.startServer(config); | ||
Configuration | ||
------------- | ||
When starting from the command line you should have `config.json` in the current working directory. | ||
When starting the server programmatically you can pass in a Javascript object for mongodb-rest configuration. | ||
Here is an example JSON configuration object: | ||
{ | ||
"db": { | ||
"port": 27017, | ||
"host": "localhost" | ||
}, | ||
"server": { | ||
"port": 3000, | ||
"address": "0.0.0.0" | ||
}, | ||
"accessControl": { | ||
"allowOrigin": "*", | ||
"allowMethods": "GET,POST,PUT,DELETE,HEAD,OPTIONS" | ||
} | ||
"humanReadableOutput": true | ||
} | ||
Supported REST API | ||
------------------ | ||
Supported REST API requests: | ||
* `GET /dbs` - Returns the names of all databases. | ||
* `GET /db/collection` - Returns all documents | ||
* `GET /db/collection?query=%7B%22isDone%22%3A%20false%7D` - Returns all documents satisfying query | ||
* `GET /db/collection?query=%7B%22isDone%22%3A%20false%7D&limit=2&skip=2` - Ability to add options to query (limit, skip, etc) | ||
* `GET /db/collection/id` - Returns document with _id_ | ||
* `POST /db/collection` - Insert new document in collection (document in POST body) | ||
* `PUT /db/collection/id` - Update document with _id_ (updated document in PUT body) | ||
* `DELETE /db/collection/id` - Delete document with _id_ | ||
* `GET /<db>/` - Returns names of all collections in the specified database. | ||
* `GET /<db>/<collection>` - Returns all documents in the specified collection. | ||
* `GET /<db>/<collection>?query=%7B%22isDone%22%3A%20false%7D` - Returns all documents satisfying query. | ||
* `GET /<db>/<collection>?query=%7B%22isDone%22%3A%20false%7D&limit=2&skip=2` - Ability to add options to query (limit, skip, etc) | ||
* `GET /<db>/<collection>/id` - Returns document with _id_ | ||
* `POST /<db>/<collection>` - Insert new document in collection (document in POST body) | ||
* `PUT /<db>/<collection>/id` - Update document with _id_ (updated document in PUT body) | ||
* `DELETE /<db>/<collection>/id` - Delete document with _id_ | ||
@@ -78,8 +125,11 @@ Flavors: | ||
Integration tests use jasmine-node. Run this command from the main folder: `jasmine-node .\ --verbose`. | ||
Integration tests use jasmine-node. | ||
Run this command from the main folder: | ||
>jasmine-node .\ --verbose | ||
Future | ||
------ | ||
Roadmap: | ||
Roadmap:<br/> | ||
https://trello.com/b/OzRxPSjO/mongodb-rest-roadmap | ||
@@ -86,0 +136,0 @@ |
@@ -14,6 +14,7 @@ /* | ||
var config = { "db": { | ||
'port': 27017, | ||
'host': "localhost" | ||
}, | ||
var defaultConfig = { | ||
"db": { | ||
'port': 27017, | ||
'host': "localhost" | ||
}, | ||
'server': { | ||
@@ -23,33 +24,40 @@ 'port': 3000, | ||
}, | ||
"accessControl": { | ||
"allowOrigin": "*", | ||
"allowMethods": "GET,POST,PUT,DELETE,HEAD,OPTIONS" | ||
}, | ||
'flavor': "regular", | ||
'debug': true | ||
'debug': true, | ||
'humanReadableOutput': true | ||
}; | ||
var app = express(); | ||
var server; | ||
try { | ||
config = JSON.parse(fs.readFileSync(process.cwd()+"/config.json")); | ||
} catch(e) { | ||
// ignore | ||
} | ||
module.exports = { | ||
app.use(require('body-parser')()); | ||
// | ||
// Start the REST API server. | ||
// | ||
startServer: function (config) { | ||
if (!config) { | ||
config = defaultConfig; | ||
} | ||
if (config.accessControl){ | ||
var accesscontrol = require('./lib/accesscontrol'); | ||
app.use(accesscontrol.handle); | ||
} | ||
var app = express(); | ||
require('./lib/rest')(app, config); | ||
app.use(require('body-parser')()); | ||
var server; | ||
if (config.humanReadableOutput) { | ||
app.set('json spaces', 4); | ||
} | ||
module.exports = { | ||
if (config.accessControl) { | ||
var accesscontrol = require('./lib/accesscontrol'); | ||
app.use(accesscontrol.handle); | ||
} | ||
// | ||
// Start the REST API server. | ||
// | ||
startServer: function () { | ||
require('./lib/rest')(app, config); | ||
console.log('Starting mongodb-rest server: ' + config.server.address + ":" + config.server.port); | ||
server = app.listen(config.server.port, config.server.address); | ||
server = app.listen(config.server.port, config.server.address); | ||
}, | ||
@@ -69,7 +77,19 @@ | ||
if (process.argv[1].indexOf('server.js') != -1) { | ||
var config = defaultConfig; | ||
// Load configuration from file. | ||
try { | ||
var configFilePath = process.cwd()+"/config.json"; | ||
config = JSON.parse(fs.readFileSync(configFilePath)); | ||
console.log("Loaded configuration from: " + configFilePath); | ||
} catch(e) { | ||
// ignore | ||
} | ||
// | ||
// Auto start server when run as 'node server.js' | ||
// | ||
module.exports.startServer(); | ||
module.exports.startServer(config); | ||
} | ||
} |
@@ -12,3 +12,4 @@ 'use strict'; | ||
var dbsUrl = url + 'dbs'; | ||
var collectionUrl = url + testDbName + '/' + testCollectionName; | ||
var collectionsUrl = url + testDbName; | ||
var collectionUrl = collectionsUrl + '/' + testCollectionName; | ||
@@ -21,3 +22,4 @@ var utils = require('./testutils'); | ||
var fixture = utils.loadFixture; | ||
var load = utils.loadFixture; | ||
var dropAndLoad = utils.dropDatabaseAndLoadFixture; | ||
var dropDatabase = utils.dropDatabase; | ||
@@ -61,3 +63,3 @@ var requestHttp = utils.requestHttp; | ||
.then(function () { | ||
return fixture(testDbName, testCollectionName, []); | ||
return dropAndLoad(testDbName, testCollectionName, []); | ||
}) | ||
@@ -76,6 +78,38 @@ .then(function () { | ||
it('can retrieve names of collections', function (done) { | ||
var testcol1 = "testcol1"; | ||
var testcol2 = "testcol2"; | ||
dropDatabase(testDbName) | ||
.then(function () { | ||
return requestJson(collectionsUrl); | ||
}) | ||
.then(function (result) { | ||
expect(result.data.length).toBe(0); | ||
}) | ||
.then(function () { | ||
return load(testDbName, testcol1, [ { blah: 1 } ]); | ||
}) | ||
.then(function () { | ||
return load(testDbName, testcol2, [ { blah: 2 } ]); | ||
}) | ||
.then(function () { | ||
return requestJson(collectionsUrl); | ||
}) | ||
.then(function (result) { | ||
var collectionNames = result.data; | ||
expect(collectionNames.length).toBeGreaterThan(1); | ||
expect(collectionNames).toContain(testcol1); | ||
expect(collectionNames).toContain(testcol2); | ||
done(); | ||
}) | ||
.catch(function (err) { | ||
done(err); | ||
}); | ||
}); | ||
it('should retreive empty array from empty db collection', function (done) { | ||
fixture(testDbName, testCollectionName, []) | ||
dropAndLoad(testDbName, testCollectionName, []) | ||
.then(function () { | ||
@@ -107,3 +141,3 @@ return collectionJson(collectionUrl); | ||
fixture(testDbName, testCollectionName, testData) | ||
dropAndLoad(testDbName, testCollectionName, testData) | ||
.then(function () { | ||
@@ -128,3 +162,3 @@ return collectionJson(collectionUrl); | ||
fixture(testDbName, testCollectionName, []) | ||
dropAndLoad(testDbName, testCollectionName, []) | ||
.then(function () { | ||
@@ -162,3 +196,3 @@ var itemID = ObjectID(); | ||
fixture(testDbName, testCollectionName, []) | ||
dropAndLoad(testDbName, testCollectionName, []) | ||
.then(function () { | ||
@@ -195,3 +229,3 @@ return itemHttp(collectionUrl, itemID); | ||
fixture(testDbName, testCollectionName, testData) | ||
dropAndLoad(testDbName, testCollectionName, testData) | ||
.then(function () { | ||
@@ -255,3 +289,3 @@ return itemJson(collectionUrl, itemID); | ||
fixture(testDbName, testCollectionName, testData) | ||
dropAndLoad(testDbName, testCollectionName, testData) | ||
.then(function () { | ||
@@ -300,3 +334,3 @@ | ||
fixture(testDbName, testCollectionName, testData) | ||
dropAndLoad(testDbName, testCollectionName, testData) | ||
.then(function () { | ||
@@ -303,0 +337,0 @@ return del(collectionUrl, itemID); |
@@ -40,36 +40,29 @@ 'use strict'; | ||
dropDatabase(testDbName) | ||
.then(function () { | ||
var db = mongojs(testDbName); | ||
var db = mongojs(testDbName); | ||
db.createCollection(testCollectionName, function (err, collection) { | ||
db.createCollection(testCollectionName, function (err, collection) { | ||
if (err) { | ||
db.close(); | ||
deferred.reject(err); | ||
return; | ||
} | ||
async.each(data, | ||
// Single async operation. | ||
function (item, callback) { | ||
collection.save(item, callback); | ||
}, | ||
// Callback after all items saved. | ||
function (err) { | ||
db.close(); | ||
if (err) { | ||
db.close(); | ||
deferred.reject(err); | ||
return; | ||
} | ||
else { | ||
deferred.resolve(); | ||
} | ||
} | ||
); | ||
}); | ||
async.each(data, | ||
// Single async operation. | ||
function (item, callback) { | ||
collection.save(item, callback); | ||
}, | ||
// Callback after all items saved. | ||
function (err) { | ||
db.close(); | ||
if (err) { | ||
deferred.reject(err); | ||
} | ||
else { | ||
deferred.resolve(); | ||
} | ||
} | ||
); | ||
}); | ||
}) | ||
.catch(function (err) { | ||
db.close(); | ||
deferred.reject(err); | ||
}) | ||
return deferred.promise; | ||
@@ -79,2 +72,13 @@ }; | ||
// | ||
// Load data into a db collection. | ||
// | ||
var dropDatabaseAndLoadFixture = function (testDbName, testCollectionName, data) { | ||
var deferred = Q.defer(); | ||
return dropDatabase(testDbName) | ||
.then(function () { | ||
return loadFixture(testDbName, testCollectionName, data); | ||
}); | ||
}; | ||
// | ||
// Request http document from the rest api. | ||
@@ -220,2 +224,3 @@ // | ||
module.exports = { | ||
dropDatabaseAndLoadFixture: dropDatabaseAndLoadFixture, | ||
dropDatabase: dropDatabase, | ||
@@ -222,0 +227,0 @@ loadFixture: loadFixture, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
56513
14
890
144