diff --git a/README.md b/README.md index fcdd708..348b1dc 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,32 @@ # deployd -Extensible, distributed, resource server. +modern, distributed, resource server. -## features +[documentation](http://deployd.github.com/deployd) + +## Features - Streaming, Any-Size File Storage - Queryable JSON Collections - Validation - Authentication - - Proxy and Redirection - - Extensible via Middleware + - Events ## Installation $ [sudo] npm install deployd -g -## Starting / Stopping +## Start -You can start and stop the server with the `dpd` CLI. For more commands see `dpd -h`. +You can start the server with the `dpd` command line interface. For more commands see `dpd -h`. $ dpd listen -or the node module - - var dpd = require('deployd') - .use('http://localhost:3333') - // optionally specify which storage resource to use - // currently only mongodb is supported - .storage('mongodb://localhost/my-dpd-storage') - // tell deployd to listen - .listen() - ; - -## Client - -The deployd api is entirely available over http. A basic http client is bundled. - - var client = require('deployd').client.use('http://localhost:2304') - , resources = client.use('/resources') - , types = client.use('/types'); - -## Node.js Module - -The HTTP Client and node module api are the same. - - var dpd = require('deployd').use('http://localhost:2304') - , resources = dpd.use('/resources') - , types = dpd.use('/types'); - ## Remote Administration -For security reasons deployd servers do not rely on human created passwords, instead deployd can be administered over http using a randomly generated auth key. +Deployd servers do not rely on human created passwords, instead deployd can be administered over http using a randomly generated auth key. -To generate a key and store it in the servers storage, use the cli. +Use the CLI to generate a unique key for remote administration. $ dpd key @@ -60,9 +34,7 @@ To generate a key and store it in the servers storage, use the cli. {_id: "...", ...} -If this key is present in the 'x-dssh-key' header of a request, it will be used to authenticate. -It should never be passed as plain text and never stored in an insecure location. Use the `dpd` cli -to regenerate and remove old keys as needed. +Requests to low level APIs such as /types and /resources will require a `x-dssh-header` containing a key generated with `dpd`. Keys can contain meta data for identifying their owner. This is useful in the case where access should be granted and revoked on a key by key basis. @@ -70,109 +42,7 @@ be granted and revoked on a key by key basis. $ dpd addkey '{"user":"joe"}' added key: {user: 'joe', _id: '...', ...} - -## Types - -`types.get([query], [callback])` or `/types` will return a description of the available resource types. - -## Collections - -### Create a collection - -Give the collection a URL and some validation and documents will only be inserted if they pass validation. - - function done(err, collection) { ... } - resources.post({ - path: '/todos', - type: 'Collection', - settings: { - title: { - description: 'the title of the todo', - type: 'string', - required: true - }, - completed: { - description: 'the state of the todo', - type: 'boolean', - default: false - } - } - }, done); - -### Add a document to the collection +## Questions - client.use('/todos').post({title: 'feed the dog'}, function(err, todo) { - console.info(err || 'it worked! saved with _id', todo._id); - }); - -## Users - -### Creating Users - -Register a user by `POST`ing a valid user object to `/users`. - - var user = { - email: 'foo@bar.com', - password: 'foobar' - }; - - client.use('/users').post(user, function(err, user) { - console.info(err || 'registered user id: ' + user._id); - }); - -### Login - -Login a user by `POST`ing a valid credentials object to `/users/login` over HTTPS. -Once a user is logged in (has created a session) all requests as the user must be -made over HTTPS. Resources that do not require a user can still be made over HTTP. - - var credentials = {email: 'foo@bar.com', password: 'foobar'}; - - client.use('/users/login').post(credentials, function(err, session) { - console.info(err || 'logged in user id: ' + session.user._id); - }); - -### Logout - -Logout a user by making any request to `/users/logout`. - - client.use('/users/logout').get(function(err) { - console.info(err || 'logged out current user'); - }); - -### Deleting Users - -Remove a user by sending a `DELETE` request to `/users?_id=`. - - client.use('/users').get({_id: user._id}).del(function(err) { - console.info(err || 'deleted user id: ' + user._id); - }); - -## Static Resources (Files) - -POST, PUT, DELETE, and GET files over http. Only root authenticated or local requests (using the node module) -are allowed to POST, PUT, or DELETE. All files are otherwise public. - -First create a static resource collection: - - resources.post({ - path: '/my-files', - type: 'Static' - }, ...); - -Then (with an auth key) post files: - - client - .addHeader('x-dssh-key', myKey) - .use('/my-files/file.jpg') - .post(fs.createReadStream('./file.jpg'), function(err) { - console.info(err || 'Streamed file.jpg to the server!'); - }) - ; - -The file will then be available to anyone over http: - - client.pipe(fs.createWriteStream('./download.jpg')).get('/my-files/file.jpg', function(err) { - console.info(err || 'Downloaded the file!'); - }); +Consult the [documentation](http://deployd.github.com/deployd) or contact `ritchie at deployd com`. \ No newline at end of file diff --git a/docs/collection.html b/docs/collection.html index 4aaed5e..09856db 100644 --- a/docs/collection.html +++ b/docs/collection.html @@ -13,7 +13,7 @@ Deployd @@ -21,265 +21,7 @@ -

Collection Resource

- -

A Collection resource allows your app to save and load data in a simple schema.

- -

Setting up a collection

- -

After creating a Collection resource in the dashboard, you can set up the schema by dragging properties into the database and naming them.

- -

The grid view below the property list allows you to edit the Collection manually.

- -

Property types

- -

You can currently use the following property types:

- - - -

Formats

- -

You must format the request body as a JSON string and pass the header "Content-Type: application/json".

- -

Saving data

- -

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)

- -

Listing data

- -

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

Retrieving a specific object

- -

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

Updating an object

- -

A PUT request at an object's URL will update the object. You must include all properties except for "_id".

- -
PUT /people/4f71fc7c2ba744786f000001
-Content-Type: application/json
-{
-  "age": 24,
-  "firstName": "Fred",
-  "lastName": "Smith"
-}
-
- -

The server will respond with the entire object:

- -
200 OK
-{
-  "_id": "4f71fc7c2ba744786f000001",
-  "age": 24,
-  "firstName": "Fred",
-  "lastName": "Smith"
-}
-
- -

Deleting an object

- -

A DELETE request at an object's URL will permanently remove that object from the collection:

- -
DELETE /people/4f71fc7c2ba744786f000001
-
-204 No Content
-
- -

Filtering results

- -

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.

- -

Advanced querying

- -

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

Collection Event Handlers

- -

You can attach micro-scripts to events to add logic and validation to your objects. Collections currently support the following events:

- - - -

Reading and setting properties

- -

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 Put:
-this.totalScore = this.level1Points + this.level2Points;
-
- -

Accessing the current user

- -

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;
-
- -

Cancelling an event

- -

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 view this post because it is not yours!", 401);
-}
-
-PUT /posts/13456
-Content-Type: application/json
-{ ... }
-
-401 Unauthorized
-{
-  "message": "You cannot view this post because it is not yours!"
-}
-
- -

Validation

- -

Use the error(name, message) function to add a validation error.

- -
//On Post
-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"
-  }
-}
-
- -

Hiding properties

- -

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');
-}
-
- -

Protecting properties from modification

- -

Use the protect(propertyName) function to protect specified properties during a POST or PUT.

- -
//On Put
-protect('createdDate');
-
+
/bin/sh: markdown: command not found
diff --git a/docs/index.html b/docs/index.html index a0f6b5c..09856db 100644 --- a/docs/index.html +++ b/docs/index.html @@ -13,7 +13,7 @@ Deployd @@ -21,66 +21,7 @@
-
-
-

Deployd

-

A modern web server for front-end developers.

-
-
- -

Basics

- -

Deployd is a web server built on resources, in the style of REST. In the dashboard, you can build your app by creating resources and configuring them to work the way the want.

- -

Routing

- -

When Deployd receives an HTTP request, it checks the first part of the URL to see which resource should handle the request:

- - - -

Reserved resource names

- -

Certain resource paths are used internally by Deployd. You should not create resources with these names:

- - - -

REST

- -

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:

- - - -

Cross-Origin AJAX

- -

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.

+
/bin/sh: markdown: command not found
diff --git a/docs/layout/header.html b/docs/layout/header.html index aaaf226..78565e5 100644 --- a/docs/layout/header.html +++ b/docs/layout/header.html @@ -13,7 +13,7 @@ Deployd diff --git a/docs/static.html b/docs/static.html index eabb4cd..09856db 100644 --- a/docs/static.html +++ b/docs/static.html @@ -13,7 +13,7 @@ Deployd @@ -21,26 +21,7 @@
-

Static Resource

- -

The Static Resource allows you host static files from your app, such as HTML, browser JavaScript, CSS, images, and videos.

- -

Accessing files

- -

Send a GET request with the filename to load the raw file. This is how browsers request pages and files by default.

- -
GET /files/bg.jpg
-
- -

Folders

- -

If you prefer to have seperate folders for Javascript, CSS, and images, create multiple Static Resources at the paths you want to store the files.

- -

You can also give a Static Resource an empty path ("/"). This will assign it to the root of your app.

- -

Home page

- -

If a Static Resource receives a request without a filename, it will automatically redirect to "index.html" if available.

+
/bin/sh: markdown: command not found
diff --git a/docs/usercollection.html b/docs/usercollection.html index f2daf8f..09856db 100644 --- a/docs/usercollection.html +++ b/docs/usercollection.html @@ -13,7 +13,7 @@ Deployd @@ -21,20 +21,7 @@
-

User Collection Resource

- -

A User Collection resource behaves much like the standard Collection resource, but adds the ability to authenticate with a username and password.

- -

Special properties

- -

The User Collection contains two special properties:

- - - -

Authenticating a user

+
/bin/sh: markdown: command not found
diff --git a/docs/usercollection.markdown b/docs/usercollection.markdown index 770949c..75827a2 100644 --- a/docs/usercollection.markdown +++ b/docs/usercollection.markdown @@ -13,3 +13,39 @@ The User Collection contains two special properties: Authenticating a user --------------------- + +First create a user by POSTing it to the root of the collection. +For this example our collection will be called `/users`. + + POST /users/login + Content-Type: application/json + { + "email": "foo@bar.com", + "password": "barfoo" + } + +To login a user, send a POST request to `//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" + } + +To logout a user send a DELETE request to `//logout`: + + 204 No Content + +The currently logged in user is available when GETing `/users/me`. + + +