DrowsyDromedary is the Ruby answer to Sleepy.Mongoose, a REST interface for MongoDB.
You'll need a working Ruby environment (tested on 1.9) with Bundler installed.
cd
into the directory where you clonedd the DrowsyDromedary source and run:
bundle
bundle exec rackup
Drowsy should now be running at http://localhost:9292, talking to your mongod
running on localhost.
Currently Drowsy cannot talk to a mongod
instance on another machine, but this will likely change in the future.
DrowsyDromedary should work with any Rack container. We use Phusion Passenger with Apache.
To deploy with Passenger:
- Clone Drowsy and create a virtual host for it.
Point the
DocumentRoot
to Drowsy'spublic
subdirectory. - Install Passenger for Apache
- cd into the Drowsy install dirctory and run:
gem install bundler
bundle --without development
DrowsyDromedary should now be up and running.
bundle
bundle exec rspec -c -fd spec.rb
By default DrowsyDromedary is wide open. This means that your entire MongoDB system will be exposed.
If you are publicly exposing your Drowsy, it is extremely important to lock down access to the service. This can be done with additional configuration to the Rack container running your app. For example, if you are deploying using Apache (via Passenger), you could limit access to specific hosts and/or implement HTTP authentication using mod_auth.
Another option is to add Rack middleware for authorization and authentication. This would be done by modifying
Drowsy's config.ru
file. Warden is a good option.
The default DrowsyDromedary configuration has an open CORS configuration. Cross-domain browser requests to Drowsy are allowed from all domains for all HTTP methods.
CORS access can be restricted by modifying the Rack::Cors
section of Drowsy's
config.ru
file.
Note that due to some questionable decisions in the CORS spec, CORS requests that result in an error
(404
, 500
, etc.) will always have a blank body (i.e. no detailed error message). In some browsers the
error status code is also obscured and always reported as 0
instead of the real code. If you want better error
handling, consider putting DrowsyDromedary behind a same-origin reverse proxy.
Date/Times values in the databse (i.e. ISODate objects) are represented in Drowsy's JSON responses as:
{ "$date": "2013-01-24T06:40:43.0Z" }
Likewise, if you want Drowsy to store a date as an ISODate, send your data in the same format. The string value can be anything parsable by Ruby's Time.parse()
, but it's probalby best to stick to the ISO8601 format. For example, in JavaScript:
var date = new Date();
dateJSON = { "$date": date.toJSON() };
Usage examples with browser-side JavaScript frameworks:
- jQuery Example
- Backbone.js Example
- Also have a look at Backbone.Drowsy
Replace db
with your database name and collection
with your collection name.
All parameters must be given as valid JSON strings, and all responses (including errors) are returned in JSON format.
List databases
Status: 200
[
"groceries",
"fridge",
"pantry"
]
Create a database
db
- The name of the database to create.
List collections in a database
[
"fruits",
"vegetables",
"snacks"
]
Create a collection in a database
collection
- The name of the collection to create.
List items in a collection
selector
- A Mongo query expression specifying which items to return.
- Examples:
{"fruit":"apple","colour":"green"}
(all items where 'fruit' is 'apple' and 'colour' is 'green'){"fruit":{"$exists":true}}
(all items that have a 'fruit' property)- Example Request:
GET
http://drowsy.example.com/fridge/crisper?selector={"fruit":{"$exists":true}}- Note that the
selector
value should be URL encoded; however most browsers will do this for you if you enter the un-encoded query in the URL bar.
- Note that the
sort
- An array of property-order pairs to sort on.
- Examples:
["fruit","DESC"]
(sort by the 'fruit' property, in descending order)["fruit","ASC"]
(sort by the 'fruit' property, in ascending order)[["fruit","ASC"],["colour","DESC"]]
(sort by the 'fruit' property first in ascending order and then by the 'colour' property in descending order)- Example Request:
GET
http://drowsy.example.com/fridge/crisper?sort=[["fruit","ASC"],["colour","DESC"]]- Note that the
sort
value should be URL encoded; however most browsers will do this for you if you enter the un-encoded query in the URL bar.
- Note that the
Status: 200
[
{
"_id": { "$oid": "4deeb1d9349c85523b000001" },
"fruit": "orange",
"colour": "orange"
},
{
"_id": { "$oid": "4deeb1d9349c85523b000002" },
"fruit": "kiwi",
"colour": "brown",
"size": "small"
},
{
"_id": { "$oid": "4deeb1d9349c85523b000003" },
"fruit": "banana",
"colour": "yellow",
"organic": true
}
]
Add an item to a collection
The request data should contain a full representation of the item to create. This can be sent either as regular, url-encoded form data
(i.e. Content-Type: application/x-www-form-urlencoded
), or as a JSON-encoded string (i.e. Content-Type: application/json
).
The server will respond with a full representation of the newly created object, with a server-generated _id
if none was provided
in the request data.
POST /groceries/cart
{
"fruit": "apple",
"colour": "red",
"variety": "Macintosh"
}
Status: 201
{
"_id": { "$oid": "4deeb1d9349c85523b000004" },
"fruit": "apple",
"colour": "red",
"variety": "Macintosh"
}
Replace an item in a collection
The request data should contain a full representation of the item to replace. This can be sent either as regular, url-encoded form data
(i.e. Content-Type: application/x-www-form-urlencoded
), or as a JSON-encoded string (i.e. Content-Type: application/json
).
If the item with the given id does not yet exist, it will be automatically created. However this behaviour is subject to change in a future version (an additional parameter may be required to enable this "upsert" behaviour).
PUT /groceries/cart/4deeb1d9349c85523b000004
{
"fruit": "apple",
"colour": "green",
"variety": "Golen Delicious"
}
Status: 200
{
"_id": { "$oid": "4deeb1d9349c85523b000004" },
"fruit": "apple",
"colour": "green",
"variety": "Golen Delicious"
}
Partially replace an item in a collection
Unlike a PUT, a PATCH request will only replace the given properties (instead of replacing the entire item).
The request data should contain a full representation of the item to replace. This can be sent either as regular, url-encoded form data
(i.e. Content-Type: application/x-www-form-urlencoded
), or as a JSON-encoded string (i.e. Content-Type: application/json
).
If the item with the given id does not yet exist, the server will respond with 404
(Not Found
).
PATCH /groceries/cart/4deeb1d9349c85523b000004
{
"colour": "orange"
}
Status: 200
{
"_id": { "$oid": "4deeb1d9349c85523b000004" },
"fruit": "apple",
"colour": "orange",
"variety": "Golen Delicious"
}
Delete an item from a collection
Note that the request will succeed regardless of whether an item with the given id exists.
DELETE /groceries/cart/4deeb1d9349c85523b000004
Status: 200
{}