Git Product home page Git Product logo

mongodb-rest's Introduction

mongodb-rest

A simple but incredibly useful REST API server for MongoDB using Node, using Express and the native node.js MongoDB driver.

As Tom has said this REST server has no security and is not fit for use in production. So be warned! Work is currently being done to improve the security of mongodb-rest, but this is still a work-in-progress.

I have found this REST server to be invaluable for rapid prototyping web applications. When you don't care about security and you just need to try something out without investing the time to build a proper secure REST API.

Recent Updates

Simple connection pooling has been added by @elabrc.

A simple token-based authentication has been added to mongodb-rest (thanks to @ZECTBynmo). This is a prototype feature only and may change in the future. I am considering making authentication plugin-based so you can roll your own if necessary. If you have any thoughts on how this should work please let us know.

Contents

Table of Contents generated with DocToc

Installation

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.

Test

After installation you can quickly test it by issuing the following from the command line:

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")
}

Start Server Programmatically

mongodb-rest can easily be started programmatically by 'requiring' the module and calling startServer.

var mongodbRest = require('mongodb-rest/server.js');
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. The project includes an example configuration file.

When starting the server programmatically you can pass in a Javascript object for mongodb-rest configuration.

Here is an example JSON configuration object:

{
    "db": "mongodb://localhost:27017",
    "endpoint_root": "server",
    "server": {
        "port": 3000,
        "address": "0.0.0.0"
    },
    "accessControl": {
        "allowOrigin": "*",
        "allowMethods": "GET,POST,PUT,DELETE,HEAD,OPTIONS",
        "allowCredentials": false
    },
    "dbAccessControl": {
        "foo_database": ["collection1", "collection2"],
        "bar_database": ["collection2", "collection3"],
        "zoo_database": [],
    },
    "mongoOptions": {
        "serverOptions": {
        },
        "dbOptions": {
            "w": 1
        }
    },
    "humanReadableOutput": true,
    "urlPrefix": "",
    "schema": {
        "foo_database": {
            "collection1": {
                "definitions": {},
                "$schema": "http://json-schema.org/draft-06/schema#",
                "$id": "http://json-schema.org/draft-06/schema#",
                "type": "object",
                "properties": {
                    "value": {
                        "$id": "/properties/value",
                        "type": "boolean",
                        "title": "Foo boolean value",
                        "description": "An explanation about the purpose of this instance.",
                        "default": false,
                        "examples": [
                            false
                        ]
                    }
                }
            }
        }
    }
}

db specifies the mongodb connection string for connection to the database. It defaults when not specified.

For documentation on the mongodb connection string: http://docs.mongodb.org/manual/reference/connection-string/

For backward compatibility db can also be set to an object that specified host and port as follows:

"db": {
    "port": 27017,
    "host": "localhost"
}

endpoint_root can have one of two values: server, database. If it is ommited, the server value is presumed. server means that we can select a database for each query, setting its name in an url, like GET /test_db/test_collection/foo_id. If instead database value is set, than connection is restricted to a single database, given in config connection options: "db": "mongodb://localhost:27017/test_db". Then all the urls should ommit db parameter. So the previous query will look like GET /test_collection/foo_id.


server specifies the configuration for the REST API server, it also defaults if not specified.


mongoOptions specifies MongoDB server and database connection parameters. These are passed directly to the MongoDB API.

Valid options under serverOptions are documented here: http://mongodb.github.io/node-mongodb-native/api-generated/server.html.

auto_reconnect is automatically enabled, don't override this or mongodb-rest may not work as expected.

Valid options under dbOptions are documented here: http://mongodb.github.io/node-mongodb-native/api-generated/db.html.

w (write concern) is set to 1 so that acknowledgement of the write is recieved by mongodb-rest, currently this must be enabled for error checking.

Set collectionOutputType to csv to returns collections as csv data rather than json.

If you are configuring the server procedurally you can assign a Javascript function to transformCollection which will transform each collection before returning it via HTTP.


The accessControl options allow you to set the following headers on the HTTP response:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Credentials

Help for these headers can be found here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS


dbAccessControl can be used for limiting access only to certain databases or collections. If ommited, user can reach to any database and collection.

If endpoint_root is set to server, than the syntax for this option is as follows:

{
    "database_name": ["collection_name1", "collection_name2"],
    "database_name2": [],
}

This example allows access only to two databases. For database_name only two collections are accesible. For database_name2 all collections are accesible.

If endpoint_root is set to database, than the syntax is as follows:

[
    "collection_name1", "collection_name2"
]

So it's just a list of accesible collections. If array is empty, all collections are accesible.


The urlPrefix option allows specification of a prefix for the REST API URLs. This defaults to an empty string, meaning no prefix which was the original behavior. For example, given the following REST API URL:

/database/collection

Setting a URL prefix of /blah will change the example REST API URL to:

/blah/database/collection

The URL prefix should allow the REST API to co-exist with another REST API and can also be used a very primitive form of security (by setting the prefix to a secret key).


schema option defines json schemas for collections. So all the documents in given collections should match defined schemas. Schema validation is performed on insert, replace and update operations. If new document does not passes schema validation, response code 400 is returned.

Logging

Winston logging is supported if you configure the REST API programmatically. When you call startServer and pass in configuration options set the logger option to your Winston logger. Mongodb-rest uses the following functions: verbose, info, warn and error.

Please see the Winston documentation for more setup details: https://github.com/flatiron/winston

Supported REST API

Listing Databases: Format: GET /dbs

$ curl 'http://127.0.0.1:3000/dbs/' \
>   -D - \
>   -H 'Accept: application/json'
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 27
ETag: W/"1b-134804454"
Date: Thu, 02 Jul 2015 08:02:26 GMT
Connection: keep-alive

[
    "local",
    "test"
]

Listing Collections: Format:GET /<db>/

$ curl 'http://127.0.0.1:3000/test/' \
>   -D - \
>   -H 'Accept: application/json'
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 27
ETag: W/"1b-134804454"
Date: Thu, 02 Jul 2015 08:02:26 GMT
Connection: keep-alive

[
   "new-collection",
   "startup_log",
   "system.indexes"
]

List Documents in a Collection: Format: GET /<db>/<collection>

$ curl 'http://127.0.0.1:3000/test/new-collection' \
>   -D - \
>   -H 'Accept: application/json'
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 27
ETag: W/"1b-134804454"
Date: Thu, 02 Jul 2015 08:02:26 GMT
Connection: keep-alive

[
    {
        "_id": "5594bf2b019d364a083f2e03",
        "attribute": "hello"
    }
]

Output a CSV collection: Format:GET /<db>/<collection>?output=csv

$ curl http://127.0.0.1:3000/test/newcollection?output=csv > Sample.csv

List documents satisfying a query: Format:GET /<db>/<collection>?query={"key":"value"}

$ curl -X "GET" http://localhost:3000/test/newcollection \
-d 'query={"attribute":"value"}
[
{
    "_id": "5594bf2b019d364a083f2e03",
    "attribute": "value"
}
]

List documents with nested queries: Format:GET /<db>/<collection>?query={"key":{"second_key":{"_id":"value"}}}

$ curl -X "GET" http://localhost:3000/test/newcollection \
    -d 'query={"attribute":{"other_attribute:{"_id":"5063114bd386d8fadbd6b004"}}}
    [
    {
        "_id": "5594bf2b019d364a083f2e03",
        "attribute": {
            other_attribute: "5063114bd386d8fadbd6b004"
        }
    }
    ]

Return document by id: Format GET /<db>/<collection>/id

$ curl -X "GET" http://localhost:3000/test/nested/5594bf2b019d364a083f2e03
{
    "_id": "5594bf2b019d364a083f2e03",
    "attribute": "hello"
}

Inserting documents: Format: POST /<db>/<collection>

$ curl 'http://localhost:3000/test/newcollection' \
>   -D - \
>   -X POST \
>   -H 'Content-Type: application/json' \
>   -H 'Accept: application/json' \
>   --data '{"title": "Some title", "content": "document content"}'

HTTP/1.1 201 CREATED
Date: Thu, 02 Jul 2015 12:50:34 GMT
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Powered-By: Express
Content-Length: 15
{
    "_id": "5595339aa73107ad070e891a",
    "title": "Some title",
    "content": "document content"
}

Replacing a document: Format: PUT /<db>/<collection>/id

$ curl -X "PUT" "http://localhost:3000/test/nested/5595339aa73107ad070e891a \
> --data {"title": "New title", "content": "New document content"}'
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Powered-By: Express
Content-Length: 15
Date: Thu, 02 Jul 2015 12:53:00 GMT
{
    "_id": "5595339aa73107ad070e891a",
    "title": "New title",
    "content": "New document content"
}

Updating a document: Format: PATCH /<db>/<collection>/id

$ curl -X "PUT" "http://localhost:3000/test/nested/5595339aa73107ad070e891a \
> --data {"title": "New title", "content": "New document content", "field_to_delete": null}'
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Powered-By: Express
Content-Length: 15
Date: Thu, 02 Jul 2015 12:53:00 GMT
{
    "_id": "5595339aa73107ad070e891a",
    "title": "New title",
    "content": "New document content"
}

Deleting a document by id: Format: DELETE /<db>/<collection>/id

$ curl -X "DELETE" "http://localhost:3000/test/nested/5595339aa73107ad070e891a
HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Powered-By: Express
Content-Length: 15
Date: Thu, 02 Jul 2015 12:53:00 GMT
{
    "ok": 1
}

Bulk write (insert, update and delete) Format: POST /<db>/bulk

$ curl 'http://localhost:3000/test/bulk' \
>   -D - \
>   -X POST \
>   -H 'Content-Type: application/json' \
>   -H 'Accept: application/json' \
>   --data '{"data": {"collection1": {"insert": [{"Title": "Some title"}, {"_id": "5595339aa73107ad070e891a", "Key": "Value"}], "update": [{"_id": 123, "New field": "new value"}]}, "collection2": {"delete": [{"name": "John"}, {"_id": "5595339aa73107ad070e891b"}]}}}'

HTTP/1.1 200 OK
Date: Thu, 02 Jul 2015 12:50:34 GMT
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Powered-By: Express
Content-Length: 15
{
    "ok": 1
}

For bulk write operation the following syntax of POST body should be used:

{
    "data": {
        "collection1": {
            "insert": [<doc1>, <doc2>, ...],
            "update": [<doc3>, <doc4>, ...],
            "delete": [<doc5>, <doc6>, ...],
        },
        "collection2": {
            "insert": [<doc1>, <doc2>, ...],
            "update": [<doc3>, <doc4>, ...],
            "delete": [<doc5>, <doc6>, ...],
        },
        ...
    }
}

So insert, update and delete operations can be performed in a single request for multiple collections.

Documents in update section should contain an _id field, that acts as a filter. The rest fields are used in mongo $set operator to update existing document.

Documents in insert and delete section are not obligated to contain _id field.

Content Type:

Please make sure application/json is used as Content-Type when using POST/PUT with request bodies.

Query options

When performing a query GET /<db>/<collection>, some options can be applyed together with filter. The following options are supported:

  • skip (int)
  • limit (int)
  • sort (object)
  • hint (object)
  • fields (object)
  • snapshot (boolean)
  • count (boolean)
  • explain (boolean)

For explain option, the explain is performed and returned for given query, no documents are returned.

For count option the response looks like {count: 24}, no documents are returned. Limit and skip options do influence the count.

An example of query with options:

    GET /<db>/<collection>?query={"key":"value"}&fields={"name":1,"surname":1}&limit=10&skip=2&snapshot=1&sort={"name":-1}&hint=index_name

Dependencies

Are indicated in package.json.

Auth

WARNING: This is a prototype feature and may change in the future.

mongodb-rest supports a simple token-based auth system. Login is accomplilshed by a HTTP POST to /login with username and password, the server will verify the user's password against a secret database. Upon authentication an access token is returned that must be attached to each subsequent API requests.

An authorization token is specified via query parameter as follows:

GET /db/collection?token=234d43fdg-34324d-dd-dsdf-f435d

Authentication is enabled by adding auth to config.json as follows:

"auth": {
	"usersDBConnection": "mongodb://localhost/auth",
	"usersCollection": "users",
	"tokenDBConnection": "mongodb://localhost/auth",
	"tokensCollectionName": "tokens",
	"universalAuthToken": "this-token-grants-universal-access-so-please-change-it",
	"tokenExpirationTimeHours": 8
}

auth requires at least:

  • usersDBConnection - mongodb connection string for the users database.
  • tokenDBConnection - mongodb connection string for the tokens database.

Here are the docs for mongodb connection strings: http://docs.mongodb.org/manual/reference/connection-string/

The following are optional:

  • usersCollection - The auth database collection where users are stored.
  • tokensCollectionName - The auth database collection where tokens are stored.
  • universalAuthToken - Specifies a token that can be used for universal authorization.
  • tokenExpirationTimeHours - Specifies the timeout in hours before tokens must be renewed by 'login'.

An example configuration example config with auth.json is included with a working authentication setup.

** Please note that mongodb exposes all databases in the server, including your secret authentication database. Move your auth database to a different server on the same machine or ensure MongoDB authentication is setup correctly. Work will be done in the future that allows particular databases to be whitelisted/blacklisted and not exposed. **

Getting the Code

You can get the code by forking/cloning the repo at:

https://github.com/codecapers/mongodb-rest.git

Testing

Integration tests use jasmine-node.

Run 'jasmine-node' from the main folder:

jasmine-node .\ --verbose

Travis-CI

https://travis-ci.org/ashleydavis/mongodb-rest

Future

Roadmap:
https://trello.com/b/OzRxPSjO/mongodb-rest-roadmap

Credits

Testing:

mongodb-rest's People

Contributors

ashleydavis avatar atanasbozhkov avatar blakmatrix avatar fcasals avatar jasny avatar kamilszot avatar marcbachmann avatar minstel avatar samyakbhuta avatar tdegrunt avatar zectbynmo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mongodb-rest's Issues

requests containing "fields" param fail

Due to an attempt at line 47 of mongodb/lib/mongodb/commands/query_command.js to treat the string value you pass from req.params.options['fields'] as an object.

TypeError: Object.keys called on non-object
        at Function.keys (native)
        at [object Object].toBinary (..../node_modules/mongodb/lib/mongodb/commands/query_command.js:47:15)

Issue can be fixed by changing lines 27-33 of your /lib/rest.js from:

var test = ['limit','sort','fields','skip','hint','explain','snapshot','timeout'];

for( o in req.query ) {
  if( test.indexOf(o) >= 0 ) {
    options[o] = req.query[o];
  } 
}

to

var options = crackQueryParams(req.query);

and adding the following function:

/*
 * Iterates over expected params and if they exist in query, adds
 * them to result after type validation and conversion
 *
 * @param {Object} Query parameters extracted from uri
 * @returns {Object} Options as expected by mongodb
 *
 * @throws if a param should be a Number but fails conversion
 * @throws if a param should be a JSON string but cannot be parsed into an object
 */
function crackQueryParams(query){
  var result={},
    expectedParamTypes={
      'explain':    Boolean,
      'snapshot': Boolean,
      'timeout':   Boolean,
      'limit':        Number,
      'skip':       Number,
      'sort':       Object,
      'fields':     Object,
      'hint':       Object
    };
  for (var t in expectedParamTypes) {
    var param = (query[t]||'').toLowerCase();
    if (param) {
      switch (expectedParamTypes[t]) {
        case Boolean:{
          if ('undefined' !== typeof param) {
            if ('string' === typeof param) {
              if ('' === param) {                                     // added to query without a value, assume true
                result[t] = true;
              }
              else if ('false' === param.toLowerCase()) {      // value is literal string 'false'
                result[t] = false;
              }
            }
            else {
              result[t] = Boolean(param);
            }
          }
          break;
        }
        case Number:{
          if(isNaN(param)) {
            throw new Error('query param[' + t + ']="'+param+'" cannnot be converted into an number');
          }
          else {
            result[t]=Number(param);
          }
          break;
        }
        case Object:{
          try {
            result[t] = JSON.parse(param);
          } 
          catch (e) {
            throw new Error('query param "' + t + '" cannnot be converted into an object:' + e);
          }
          break;
        }
      }
    }
  }
  return result;
}

query string

using a query string with a GET /db/col isnt working.
Debugging the code it appears that in rest.js code uses req.params to extract the parameters passed within the url's query component (the bit after the "?" of a url).
Shouldnt it be using req.query object instead to get to any of the parameters of the url's query component? (kinda confusing since "query" is used as a parameter name within the url's query :) )

This is for both req.params.query and req.params.option lines.
i.e. They should be req.query.query and req.query.option respectively.

Also since they are strings should they not also be evaled or json.evaled before being passed to find() ?

query by ID fails.

127.0.0.1/db/collection?query={"_id":"4fe1ef888596c2f014000006"}
does not return specified object.

Error resultsing from GET request: http://127.0.0.1:3000/db/collection/id

I might be coming from a position of ignorance as this is a second attempt as getting a nodejs project up and running. But is have followed the instructions provided within the README.md text file.

As far as i know i have jade, express and mongo npm packages installed. And within the folder /usr/local/lib/node/.npm/mongodb-rest/active/node_modules they all appear within their respective folders.

The service works fine expect when attempting to retrieve a specific record using the uri structure: http://127.0.0.1:3000/db/collection/id, in my case: http://127.0.0.1:3000/flockworks/agent/4d94aaadd23d5b010c000001. In which case the follow error occurs:

TypeError: undefined is not a function
at CALL_NON_FUNCTION_AS_CONSTRUCTOR (native)
at Object. (/usr/local/lib/node/.npm/mongodb-rest/0.6.7/package/lib/rest.js:22:21)
at param (/usr/local/lib/node/.npm/connect/1.2.1/package/lib/middleware/router.js:148:21)
at param (/usr/local/lib/node/.npm/connect/1.2.1/package/lib/middleware/router.js:159:15)
at param (/usr/local/lib/node/.npm/connect/1.2.1/package/lib/middleware/router.js:159:15)
at param (/usr/local/lib/node/.npm/connect/1.2.1/package/lib/middleware/router.js:159:15)
at pass (/usr/local/lib/node/.npm/connect/1.2.1/package/lib/middleware/router.js:164:10)
at Object.router as handle
at next (/usr/local/lib/node/.npm/connect/1.2.1/package/lib/http.js:204:15)
at Object.logger as handle

I have investigated the line error number:
query = {'_id': new mongo.ObjectID(req.params.id)};

The parameter req.params.id seems to be set.

Whereas sending a query URL request like '?query={"accountid":"myaccountID"}' works just fine.

i rolled back from node 0.5.0-pre to node 0.4.5 (node --version), as far as i can tell here are the .npm package versions:

Platform Ubuntu 10.10

Any ideas?

Handling Documents that do not have ObjectID

I have a program that is storing documents in MongoDB, but the program is creating it's own object ID (which is just a UUID). See example documents:

{ "_id" : "e5e781f9-2947-4198-adca-f4d452e98c1a", "isDone" : false, "description" : "New Task" }
{ "_id" : "07cea259-f333-4836-a53f-644d2428a382", "isDone" : false, "description" : "New Task" }
{ "_id" : "1dcf6de5-c634-44c4-b5d9-9e349612ed46", "isDone" : false, "description" : "New Task" }
{ "_id" : "dfd31230-4293-4539-aa55-292297474ec4", "isDone" : false, "description" : "New Task" }

When trying to pull these documents through mongodb-rest, I receive the following error:

node.js:178
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Object e5e781f9-2947-4198-adca-f4d452e98c1a has no method 'toHexString'
at Object.flavorize (/usr/local/lib/node/.npm/mongodb-rest/0.6.7/package/lib/util.js:22:25)
at /usr/local/lib/node/.npm/mongodb-rest/0.6.7/package/lib/rest.js:50:32
at Array.forEach (native)
at /usr/local/lib/node/.npm/mongodb-rest/0.6.7/package/lib/rest.js:49:18
at /usr/local/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/cursor.js:122:15
at /usr/local/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/cursor.js:167:11
at /usr/local/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/cursor.js:467:28
at [object Object].close (/usr/local/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/cursor.js:625:17)
at [object Object].nextObject (/usr/local/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/cursor.js:467:10)
at Array. (/usr/local/lib/node/.npm/mongodb/0.9.2/package/lib/mongodb/cursor.js:161:12)

On line 21 of the /lib/util.js package, a suggestion would be to put another 'if' statement to check if the _id is a Mongo ObjectID or just a string. Something like:

if (id == ObjectID) {
doc._id = doc._id.toHexString();
} else {
// leave doc._id alone
}

Just a suggestion, this could be a rare case since most people let Mongo (or the driver) create the ObjectID. This just happens where the project I'm on, I'm given a unique ID that is mapped to other data sources outside of Mongo via this UUID.

Great work, thanks.

Matt

Can't run from the command line

This is my build output:

[email protected] install /Users/username/Desktop/tdegrunt-mongodb-rest-315dc34/node_modules/mongodb-rest/node_modules/mongodb
bash ./install.sh

uname: illegal option -- o
usage: uname [-amnprsv]
Not building native library for cygwin
make -C ./external-libs/bson
rm -rf build .lock-wscript bson.node
node-waf configure build
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for node path : not found
Checking for node prefix : ok /usr/local
'configure' finished successfully (0.171s)
Waf: Entering directory /Users/username/Desktop/tdegrunt-mongodb-rest-315dc34/node_modules/mongodb-rest/node_modules/mongodb/external-libs/bson/build' [1/9] cxx: bson.cc -> build/default/bson_1.o [2/9] cxx: long.cc -> build/default/long_1.o [3/9] cxx: objectid.cc -> build/default/objectid_1.o [4/9] cxx: binary.cc -> build/default/binary_1.o [5/9] cxx: code.cc -> build/default/code_1.o [6/9] cxx: dbref.cc -> build/default/dbref_1.o [7/9] cxx: timestamp.cc -> build/default/timestamp_1.o [8/9] cxx: local.cc -> build/default/local_1.o [9/9] cxx_link: build/default/bson_1.o build/default/long_1.o build/default/objectid_1.o build/default/binary_1.o build/default/code_1.o build/default/dbref_1.o build/default/timestamp_1.o build/default/local_1.o -> build/default/bson.node Waf: Leaving directory/Users/username/Desktop/tdegrunt-mongodb-rest-315dc34/node_modules/mongodb-rest/node_modules/mongodb/external-libs/bson/build'
'build' finished successfully (4.014s)
=== EXECUTING TEST_BSON ===
=== EXECUTING TEST_FULL_BSON ===
[email protected] ./node_modules/mongodb-rest
├── [email protected]
├── [email protected]
└── [email protected]

but then when I type mongodb-rest at the command line I get the error:
mongodb-rest: command not found

Any ideas?

Route errors from router.js

I'm getting an error from middleware/router.js. I start up the server, and send a GET /db/collection/id request. The error response is:

SyntaxError: Unexpected token ILLEGAL
at Object.parse (native)
at Object. (/usr/local/lib/node/.npm/mongodb-rest/0.6.4/package/lib/rest.js:18:20)
at param (/usr/local/lib/node/.npm/connect/0.5.3/package/lib/connect/middleware/router.js:145:21)
at param (/usr/local/lib/node/.npm/connect/0.5.3/package/lib/connect/middleware/router.js:156:15)
at param (/usr/local/lib/node/.npm/connect/0.5.3/package/lib/connect/middleware/router.js:156:15)
at param (/usr/local/lib/node/.npm/connect/0.5.3/package/lib/connect/middleware/router.js:156:15)
at pass (/usr/local/lib/node/.npm/connect/0.5.3/package/lib/connect/middleware/router.js:161:10)
at Object.router as handle
at next (/usr/local/lib/node/.npm/connect/0.5.3/package/lib/connect/index.js:236:15)
at Object.logger as handle

Using express 1.0.1, node 0.2.6, mongodb 1.6.5, mongodb-rest 0.6.4, mongodb node driver 0.7.9. All software (except node and mongodb) installed using npm.

Crash on ObjectID.createFromHexString call

When sending a PUT and trying to update an existing document, NodeJS crashes with:

mongodb-rest/lib/mongodb_rest.js:209
var spec = {'_id': mongo.ObjectID.createFromHexString(parameters['id'])};
                               ^
TypeError: Cannot call method 'createFromHexString' of undefined
at [object Object].updateDocument (mongodb-rest/lib/mongodb_rest.js:209:36)

My request is:

PUT /db/coll/4c6eb1c31d2df02815fb57f1 HTTP/1.1

{ "attribute": "hello" }

Update mongo nodejs driver

When performing npm install, the following message appears:

npm WARN deprecated [email protected]: Please upgrade to 2.2.19 or higher

With this version of driver, app does not work with mongodb version 3.x, only with 2.x. When running tests with mongodb 3.x, they fail with the message:

MongoError: The field 'strict' is not a valid collection option. Options: { strict: true }

Also current version of driver does not support using promises, that could have make the code much shorter.

How to start this?

I ran install, test, added a configs, have a running mongodb instance.

Tried to run the global package, created a local one ...

Server starts, but can't query anything.

Revive and support this project

@tdegrunt I noticed that this project is abandoned. Is it possible for us to revive it and take control? We'd revise the code, but the funtionality would remain. Additionally we would add JSONSchema validation and Elastic Search support.

You can contact me via e-mail at [email protected] (:netherlands:).

Cannot call method 'collection' of null

var Db = require('mongodb').Db;
var Server = require('mongodb').Server;
new Db('db-login', new Server('localhost', '27017'));
var db = new Db('db-login', new Server('localhost', '27017', { auto_reconnect: true },{safe:false}));

db.open(function (err, db) {
if (err) { console.log(err + ' db open error') }
db.authenticate('jones', 'jones', function (err, result) {
if (err) { console.log(err + ' auth error'); }
else{ console.log('Authenticated..'); }
});
});

exports.getlogin=function getlogin(uid,pwd,callback){
Db.connect('mongodb://admin:markingof@localhost:27017/db-login', function (err, db) {
db.collection('maccount_logins', function(err, collection) {

collection.find({"user.userid":uid,"user.pwd":pwd,"user.status":"true"},{"acc_type":"","acc_prefix":"","db_name":"","user.role":"","_id":0}).toArray(function(err, items) {
    if(err){console.log(err+'i am stuck');}
    else{

            callback("",items);
    }



 });

});
});
};

Bulk Updates

It would be great to have bulk update capabilities (like in CouchDB), ie:

$ DB="http://127.0.0.1:5984/tstconf"
$ curl -d '{"docs":[{"key":"baz","name":"bazzel"},{"key":"bar","name":"barry"},   {"key":"zap","_deleted":true}]}' -X POST  "$DB/_bulk_docs"

Properties on each document can indicate if it should be inserted, updated or deleted.
docs could be grouped by collection, too.

The CouchDB bulk update could be used as model:
http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API

POST response could (should?) include JSON for newly created resource

Currently a successful POST (create) results in a response that just says {"ok":1} and provides a Location header with the URL where the newly created resource can be retrieved.

This is problematic in several cases. For one, it will generally not work for POSTs done over CORS, because (for very bad reasons), the "Location" header is stripped by browsers from CORS responses. This makes retrieving info about the resource after creation impossible.

It also just doesn't work with certain REST libraries—batman.js's RestStorage is one I've had problems with—because they expect the newly created resource's data be available in the POST response body.

I'm willing to implement a solution to this. Maybe an optional config setting to enable returning the resource JSON in the POST response? But is there a good reason why I might not want to implement this?

Elasticsearch query syntax

In addition to the query parameter, also support a q parameter. This uses the Elasticsearch uri query syntax.

The query should be converted to a MongoDB filter. Do not query to Elasticsearch.

  • ?q=tag:foo
  • ?q=user.id:12345
  • ?q=date:[2018-01-01 TO 2018-12-31]

https://www.elastic.co/guide/en/elasticsearch/reference/6.3/query-dsl-query-string-query.html#query-string-syntax
https://www.elastic.co/guide/en/kibana/current/lucene-query.html
https://www.elastic.co/guide/en/kibana/current/kuery-query.html

Queries will not do a full text search, so status:active doesn't mean status contains active, but status is active.

DeprecationWarning for some dependencies

the next command line npx mongodb-rest returns:

body-parser deprecated bodyParser: use individual json/urlencoded middlewares node_modules/mongodb-rest/server.js:102:35
body-parser deprecated undefined extended: provide extended option node_modules/body-parser/index.js:105:29
js-bson: Failed to load c++ bson extension, using pure JS version
(node:10239) [DEP0025] DeprecationWarning: sys is deprecated. Use util instead.

Add Support for JSONP

I am trying to create a website using jQuery where my application is on a different server than mongodb-rest. In order to query mongodb-rest on another server, it has to be able to support JSONP. There is a really good example of this here:

http://www.jsonpexamples.com/jsonp-rating-example-using-jquery/

In short, JSONP wraps the JSON response in a callback method. For example, using mongodb-rest as it is today I get:

Call: http://localhost:3000/foo/bar/
Response: [{"_id":"4d91e32a7a3a4172cd000000","x":1}]

To support JSONP, you need to add the callback method to the Call and then wrap the response with the method name. For example:

Call: http://localhost:3000/foo/bar/?callback=writeResponse
Response: writeResponse({"_id":"4d91e32a7a3a4172cd000000","x":1})

Then my jQuery method writeResponse(data) can parse the JSON and complete processing.

The implementation doesn't seem to bad:
1.) Parse incoming request URL, if the term "callback=?" is found, save the callback value to wrap the JSON response.
2.) Pull JSON from Mongo and instead of responding with [{myjson}], the response would be myFunction({myjson}).

Thanks for your help.

Matt

npm installation Error: Failed to parse json


~: npm -v
0.3.14
~: npm install mongodb-rest
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info fetch http://registry.npmjs.org/mongodb-rest/-/mongodb-rest-0.6.5.tgz
npm info calculating sha1 /var/folders/a6/a6J4vqmgH8CZGccz9mAojE+++TM/-Tmp-/npm-1299279871555/1299279871555-0.3240684389602393/tmp.tgz
npm info shasum b4f3380b84532d288aed409aefdd266ee64d50f7
npm ERR! couldn't read package.json in /var/folders/a6/a6J4vqmgH8CZGccz9mAojE+++TM/-Tmp-/npm-1299279871555/1299279871555-0.3240684389602393/contents/package
npm ERR! Error installing [email protected]
npm ERR! Error: Failed to parse json
npm ERR! Unexpected token ]
npm ERR!     at jsonParseFail (/usr/local/lib/node/.npm/npm/0.3.14/package/lib/utils/read-json.js:89:11)
npm ERR!     at /usr/local/lib/node/.npm/npm/0.3.14/package/lib/utils/read-json.js:82:14
npm ERR!     at P (/usr/local/lib/node/.npm/npm/0.3.14/package/lib/utils/read-json.js:62:40)
npm ERR!     at cb (/usr/local/lib/node/.npm/npm/0.3.14/package/lib/utils/graceful-fs.js:31:9)
npm ERR!     at [object Object]. (fs.js:86:5)
npm ERR!     at [object Object].emit (events.js:39:17)
npm ERR!     at afterRead (fs.js:843:12)
npm ERR! JSON.parse 
npm ERR! JSON.parse Failed to parse package.json data.
npm ERR! JSON.parse Note that package.json must be actual JSON, not
npm ERR! JSON.parse just a JavaScript object.
npm ERR! JSON.parse 
npm ERR! JSON.parse This changed in npm 0.3.0, and is not a bug in npm.
npm ERR! JSON.parse Tell the package author to fix their package.json file.
npm ERR! JSON.parse
npm ERR! System Darwin 10.6.0
npm ERR! argv { remain: [ 'mongodb-rest' ],
npm ERR! argv   cooked: [ 'install', 'mongodb-rest' ],
npm ERR! argv   original: [ 'install', 'mongodb-rest' ] }
npm not ok

server crashes on update

When performing a PUT on a document the server always crashes with

TypeError: Cannot read property '_id' of undefined
    at ... /mongodb-rest/lib/rest.js:138:68
    at ... /mongodb-rest/node_modules/mongodb/lib/mongodb/collection/core.js:572:7
    at ... /mongodb-rest/node_modules/mongodb/lib/mongodb/db.js:1131:7
    at ... /mongodb-rest/node_modules/mongodb/lib/mongodb/db.js:1847:9
    at Server.Base._callHandler (... /mongodb-rest/node_modules/mongodb/lib/mongodb/connection/base.js:445:41)
    at ... /mongodb-rest/node_modules/mongodb/lib/mongodb/connection/server.js:478:18
    at MongoReply.parseBody (... /mongodb-rest/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
    at null.<anonymous> (... /mongodb-rest/node_modules/mongodb/lib/mongodb/connection/server.js:436:20)
    at emit (events.js:95:17)
    at null.<anonymous> (... /mongodb-rest/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:201:13)

Reverse sort order

In the following exemple, I try to sort the result with a desc order

$ curl -d '{ "A1" : 201 }' -H "Content-Type: application/json" http://localhost:3000/test/example1
$ curl -d '{ "A1" : 3 }' -H "Content-Type: application/json" http://localhost:3000/test/example1
$ curl -d '{ "A1" : 307 }' -H "Content-Type: application/json" http://localhost:3000/test/example1

Sort asc (easy) :

$ curl http://localhost:3000/test/example1?sort=A1

[
  {"A1":3,"_id":"4ed3aee8cc4fc51e1a000002"},
  {"A1":201,"_id":"4ed3aedccc4fc51e1a000001"},
  {"A1":307,"_id":"4ed3aeedcc4fc51e1a000003"}
]

But how can I do a desc sort:

I tried with:

> encodeURI("{A1:-1}")
'%7BA1:-1%7D'


$ curl http://localhost:3000/test/example1?sort=%7BA1:-1%7D

[
  {"A1":201,"_id":"4ed3aedccc4fc51e1a000001"},
  {"A1":3,"_id":"4ed3aee8cc4fc51e1a000002"},
  {"A1":307,"_id":"4ed3aeedcc4fc51e1a000003"}
]

But it doesn't work.

CURL Example Code

After reading the code I learned how to use the CURL command to use the REST interface:

curl -d '{ "A1" : 201 }' -H "Content-Type: application/json" http://localhost:3000/test/example1

Value Added to the "test" db.example1 collection:
{
"A1": 201,
"_id": ObjectId("4e90e196b0c7f4687000000e")
}

You may want to add this example the the Introduction to help explain the exact use the code.

This comes from the header of the file:

/mongodb-rest/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js

This was a great help to me in testing my new code.

Cannot call method 'collection' of null

I'm trying to connect mongodb-rest to a 1.6.1 version of MongoDB. When I try to get my collection, node crashes with:

    db.collection(parameters['collection'], function(err, collection) {
 ^
TypeError: Cannot call method 'collection' of null
at lib/mongodb_rest.js:172:6

Endpoint on database level

Add a endpoint_root option for the configuration. This can be 'server' or 'database'. If it's 'database', the endpoints should be:

  • GET /collection - Returns all documents
  • GET /collection?query=%7B%22isDone%22%3A%20false%7D - Returns all documents satisfying query
  • GET /collection?query=%7B%22isDone%22%3A%20false%7D&limit=2&skip=2 - Ability to add options to query (limit, skip, etc)
  • GET /collection/id - Returns document with id
  • POST /collection - Insert new document in collection (document in POST body)
  • PUT /collection/id - Replace document with id (updated document in PUT body)
  • PATCH /collection/id - Update document with id (updates in PATCH body)
  • DELETE /collection/id - Delete document with id

Not able to start

Greetings,

I'm trying to get mongodb-rest running on Ubuntu 10.10. I have node.js and npm installed:

me@TestBox:~/dev_apps$ sudo npm install mongodb-rest
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info preinstall [email protected]
npm info install [email protected]
npm info postinstall [email protected]
npm info predeactivate [email protected]
npm info deactivate [email protected]
npm info postdeactivate [email protected]
npm info preactivate [email protected]
npm info activate [email protected]
npm info postactivate [email protected]
npm info build Success: [email protected]
npm ok

me@TestBox:~/dev_apps$ sudo mongodb-rest

node.js:178
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Object # has no method 'bodyDecoder'
at HTTPServer. (/usr/local/lib/node/.npm/mongodb-rest/0.6.6/package/server.js:29:21)
at HTTPServer.configure (/usr/local/lib/node/.npm/express/2.1.1/package/lib/http.js:434:8)
at Object. (/usr/local/lib/node/.npm/mongodb-rest/0.6.6/package/server.js:28:5)
at Module._compile (module.js:404:26)
at Object..js (module.js:410:10)
at Module.load (module.js:336:31)
at Function._load (module.js:297:12)
at require (module.js:348:19)
at Object. (/usr/local/lib/node/.npm/mongodb-rest/0.6.6/package/bin/mongodb-rest:8:17)
at Module._compile (module.js:404:26)

Looking to get an example running with SproutCore and Mongo, your REST interface looks perfect. Any help would be much appreciated, thanks.

Matt

sort and fields, and other options

After a quick test of the various query options, I find

?query={"city":"foo"}&fields={"name":1}     crashes server
?query={"city":"foo"}&hint={"name":1}       crashes server
?query={"city":"foo"}&sort={"name":-1}      ignored
?query={"city":"foo"}&explain=1             crashes server

The first three can be fixed by changing line 31 of rest.js from

options[o] = req.query[o];

to

options[o] = JSON.parse(req.query[o]);

But it should be noted that the server code for this project is VERY brittle, lacking any sort of defensive programming or error-handling.

jade dependency

Hi,

you have to add jade into depenencies array in package.json, because jade is not installed per default if installing express.

runs slow

In looking at the code, i realized you are opening and closing a database connection each time a request is made.

For extra speed, consider leaving the connection open for all requests, and never closing the connection.

JSON Schema support

Add JSON Schema support. For each endpoint / collection you should be able to configure a schema.

When adding / updating return a 400 bad request if document doesn't validate.

how do I run mongodb-rest from windows ?

hello, I just installed mongodb-rest via npm:

C:\dev\apps\nodejs\node_modules\npm\node_modules>npm install mongodb-rest
npm http GET https://registry.npmjs.org/mongodb-rest
npm http 304 https://registry.npmjs.org/mongodb-rest
npm http GET https://registry.npmjs.org/express
[...]

and it seems to install finely.

but running "mongodb-rest" doesn't work (command not found). I even tried the launcher in "mongodb-rest\bin" but it's a bash script.

Notabene: I'm quite new to both Npm and Mongo.

Update Elasticsearch index

When adding and updating documents, optionally update the Elasticsearch index to include the (updated) document. The Elasticsearch endpoint must be configured. The index name should be configurable per collection and default to {db}-{collection}.

Note: Elasticsearch already has a REST API. This project won't proxy the search api.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.