Deployd lets you quickly build secure, dynamic JavaScript and Mobile apps without writing backend code. Instead you boot a simple server that is very good at securely proxying requests to a storage layer such as a database. This enables your un-trusted client code to do things it never could before, such as write directly to a database without a custom application running in-between.
Instead of reinventing a protocol, deployd embraces HTTP. This means that any HTTP client, such as a JavaScript app, a mobile app, or even another server, can securely interact with your data without having to setup a web server and write a custom backend.
Currently deployd requires mongodb to be installed. You can download it here.
Deployd also requires node.js >= v0.6.0. You can download it here.
Install deployd from npm (requires [nodejs(http://www.mongodb.org/downloads), mongodb).
$ [sudo] npm install deployd -g
Create an index.html file in a new directory.
$ cat >> index.html
hello world!
^C
Run deployd from the directory where you want to server your files.
$ dpd -d
This will open up the dashboard where you can manage your deployd server.
See dpd -h for more info on how to use the command line interface.
When deployd receives an HTTP request, it checks the first part of the URL to see which resource should handle the request:
Once deployd knows what resource is being requested, it will validate the input, execute any event handlers you have defined and either return or store the result. You can create and configure resources and event handlers in the dashboard.
REST is a web service design pattern that conforms closely to HTTP itself. In Deployd, HTTP methods or verbs have meaning:
In Deployd, HTTP response codes are also important:
Deployd is configured so that you can easily develop a web app locally on your computer. It will send Access-Control-Allow-Origin HTTP headers if a request is coming from localhost or your filesystem, which will allow modern web browsers to use AJAX normally. It will not send these headers for any other domain.
A Collection resource allows client apps to save and query data.
After creating a Collection resource in the dashboard, you can set up the schema that will automatically validate data sent to the resource url over HTTP. You can configure this schema in the dashboard.
The Data view in the dashboard allows you to edit the Collection manually.
You can currently use the following property types:
When POSTing or PUTing data to a resource /path, you must format the request body as a JSON string and pass the header "Content-Type: application/json".
To save data, send a POST request to the root of the Collection:
POST /people
Content-Type: application/json
{
"age": 23,
"firstName": "Joe",
"lastName": "Smith"
}
The server will respond with the object, which will have a new _id property.
200 OK
{
"_id": "4f71fc7c2ba744786f000001",
"age": 23,
"firstName": "Joe",
"lastName": "Smith"
}
This _id is used to find the object's URL (i.e. /people/4f71fc7c2ba744786f000001)
A GET request to the root of the Collection will return an array of objects in the collection:
GET /people
200 OK
[
{
"_id": "4f71fc7c2ba744786f000001",
"age": 23,
"firstName": "Joe",
"lastName": "Smith"
},
{
"_id": "4f71fe8b2ba744786f000002",
"age": 36,
"firstName": "John",
"lastName": "Doe"
}
]
A GET request at an object's URL will return the properties of that object:
GET /people/4f71fc7c2ba744786f000001
200 OK
{
"_id": "4f71fc7c2ba744786f000001",
"age": 23,
"firstName": "Joe",
"lastName": "Smith"
}
A PUT (or POST) request at an object's URL will update the properties specified on the object.
PUT /people/4f71fc7c2ba744786f000001
Content-Type: application/json
{
"age": 24
}
The server will respond with the entire object:
200 OK
{
"_id": "4f71fc7c2ba744786f000001",
"age": 24,
"firstName": "Fred",
"lastName": "Smith"
}
A DELETE request at an object's URL will permanently remove that object from the collection:
DELETE /people/4f71fc7c2ba744786f000001
204 No Content
You can add querystring parameters to a GET request at the root to filter the results by properties specified:
GET /people?firstName=Joe&lastName=Smith
NOTE: This currently only works for String properties.
If you need to query additional types of properties, pass a JSON object as the q parameter with the properties you wish to filter:
GET /people?q={
"age": 23
}
The q parameter supports MongoDB's query language for particularly advanced queries. Note that Collections do not currently support embedded documents or arrays.
GET /people?q={
"$orderby": { "age": 1 },
"name": {
"$regex": "^j"
"$options": "i",
}
}
You can attach micro-scripts to events to add logic and validation to your objects. Collections currently support the following events:
In an event micro-script, the this object refers to the current object, and has all of the properties of the object.
You can set values on the this object during an On Post or On Put event. These changes will be saved to the database.
// On POST:
this.dateCreated = new Date();
// On Validate:
this.totalScore = this.level1Points + this.level2Points;
Note: If you intend for a property to be "automatic" (calculated by the server, and never provided by the client), you will need to mark it as Optional in the dashboard.
If the request is coming from a logged in User, you can use the "me" object to access their properties.
// On POST:
this.creator = me._id;
You can stop any event by calling the cancel(message, [code]) method.
//On DELETE:
if (this.protected) {
cancel('This post is protected and cannot be deleted');
}
DELETE /posts/123456
400 Bad Request
{
"message": "This post is protected and cannot be deleted"
}
You can pass an integer to the cancel() method as the second parameter to set the HTTP status code. For example, 401 means "Unauthorized".
//On PUT
if (this.creator !== me._id) {
cancel("You cannot edit this post because it is not yours!", 401);
}
PUT /posts/13456
Content-Type: application/json
{ ... }
401 Unauthorized
{
"message": "You cannot edit this post because it is not yours!"
}
Use the error(name, message) function to add a validation error.
//On Validate
if (this.age < 18) {
error('age', 'must be older than 18')
}
POST /people
{
"firstName": "Joe",
"lastName": "Smith",
"age": 12
}
400 Bad Request
{
errors: {
"age": "must be older than 18"
}
}
If you wish to hide certain properties from a user, use the hide(propertyName) function.
//On Get
if (this.creator !== me._id) {
hide('lastName');
hide('age');
}
Use the protect(propertyName) function to protect specified properties during a PUT.
//On Put
protect('createdDate');
The Files Resource allows you host static files from your app, such as HTML, browser JavaScript, CSS, images, and videos.
The Files Resource is always included in your app.
Send a GET request with the filename to load the raw file. This is how browsers request pages and files by default.
GET /register.html
GET /images/bg.jpg
If the Files Resource receives a request without a filename, it will automatically redirect to "index.html" if available.
A User Collection resource behaves much like the standard Collection resource, but adds the ability to authenticate with a username and password.
The User Collection contains two special properties:
First create a user by POSTing it to the root of the collection.
For this example our collection will be called /users.
POST /users
Content-Type: application/json
{
"email": "foo@bar.com",
"password": "barfoo"
}
To login a user, send a POST request to /<collection name>/login:
POST /users/login
Content-Type: application/json
{
"email": "foo@bar.com",
"password": "barfoo"
}
The server will respond with the user, without the password.
200 OK
{
"_id": "4f71fc7c2ba744786f000001",
"email": "foo@bar.com"
}
The currently logged in user is available by sending a GET request to /users/me.
200 OK
{
"_id": "4f71fc7c2ba744786f000001",
"email": "foo@bar.com"
}
To logout a user send a POST request to /<collection name>/logout:
204 No Content