Dpd.js for Custom Resources #

Because Custom Resource Types can specify APIs very different from a Collection, Dpd.js acts as a generic HTTP library for Custom Resources.

Accessing the Resource #

The API for your Resource is automatically generated as dpd.[resource].

Examples:

dpd.emails
dpd.addfollower
dpd.uploads

Note: If your Resource name has a dash in it (e.g. /add-follower), the dash is removed when accessing it in this way (e.g. dpd.addfollower).

You can also access your resource by using dpd(resourceName) as a function.

Examples:

dpd('emails')
dpd('add-follower')
dpd('uploads')

Callbacks #

Every function in the Dpd.js API takes a callback function (represented by fn in the docs) with the signature function(result, error).

The callback will be executed asynchronously when the API has received a response from the server.

The result argument differs depending on the function. If the result failed, it will be null and the error argument will contain the error message.

The error argument, if there was an error, is an object:

  • status (number): The HTTP status code of the request. Common codes include:
    • 400 - Bad Request: The request contained invalid data and could not be completed
    • 401 - Unauthorized: The current session is not authorized to perform that action
    • 500 - Internal Server Error: Something went wrong on the server
  • message (string): A message describing the error. Not always present.
  • errors (object): A hash of error messages corresponding to the properties of the object that was sent - usually indicates validation errors. Not always present.

Examples of errors:

{
    "status": 401,
    "message": "You are not allowed to access that resource!"
}
{
    "status": 400,
    "errors": {
        "title": "Title must be less than 100 characters",
        "category": "Not a valid category"
    }
}

Promises #

Every function in the collection API returns a promise. We use the ayepromise library (which follows the Promises/A+ 1.1 specs). To learn how to use promises, please, refer to this article.

The first callback contains the same result same with the classic callbacks. The second callback contains the error object as described above. Here's an example to use promises within dpd.js:

dpd.todos.post({message: "Hello world"}).then(function(todo) {
    // do something with todo
    console.log(todo); // display {id: "###", message: 'Hello world'}
}, function(err) {
    // do something with the error
    console.log(err); // display an error if the request failed
});
dpd.todos.get('1234324324').then(function(todo) {
    // do something with todo
    console.log(todo); // display {id: "###", message: 'Hello world'}
}, function(err) {
    // do something with the error
    console.log(err.errors.message); // display the error message
});

get() #

dpd.[resource].get([func], [path], [query], fn)

Makes a GET HTTP request at the URL /<resource>/<func>/<path>, using the query object as the query string if provided.

  • func - A special identifier, i.e. /me.
  • path - An identifier for a particular object, usually the id
  • query - An object defining the querystring. If the object is complex, it will be serialized as JSON.
  • fn - Callback function(result, error).

post() #

dpd.[resource].post([path], [query], body, fn)

Makes a POST HTTP request at the URL /<resource>/<path>, using the query object as the query string if provided and body as the request body.

  • path - An identifier for a particular object, usually the id
  • query - An object defining the querystring. If the object is complex, it will be serialized as JSON.
  • body - The body of the request; will be serialized as JSON and sent with Content-Type: application/json header.
  • fn - Callback function(result, error).

put() #

dpd.[resource].put([path], [query], body, fn)

Makes a PUT HTTP request at the URL /<resource>/<path>, using the query object as the query string if provided and body as the request body.

  • path - An identifier for a particular object, usually the id
  • query - An object defining the querystring. If the object is complex, it will be serialized as JSON and passed as the q parameter.
  • body - The body of the request; will be serialized as JSON and sent with Content-Type: application/json header.
  • fn - Callback function(result, error).

del() #

dpd.[resource].del([path], [query], fn)

Makes a DELETE HTTP request at the URL /<resource>/<path>, using the query object as the query string if provided.

  • path - An identifier for a particular object, usually the id
  • query - An object defining the querystring. If the object is complex, it will be serialized as JSON and passed as the q parameter.
  • fn - Callback function(result, error).

exec() #

dpd.[resource].exec(func, [path], [body], fn)

Makes an RPC-style POST HTTP request at the URL /<resource>/<func>/<path>. Useful for functions that don't make sense in REST-style APIs, such as /users/login.

  • func - The name of the function to call
  • path - An identifier for a particular object, usually the id
  • body - The body of the request; will be serialized as JSON and sent with Content-Type: application/json header.
  • fn - Callback function(result, error).

Realtime API #

The Generic Realtime API behaves the same way as the Collection Realtime API.

Event API for Custom Resources #

Background #

Custom Resources may load event scripts to allow you to inject business logic during requests to the resource. For example, the collection resource exposes an event called validate. Given the following todo resource folder:

/my-app
  /resources
    /todos
      validate.js

The collection resource would load the contents of validate.js as the validate event.

Default Event Script Domain #

Event scripts do not share a global scope with other modules in your app. Instead each time an event script is run, a new scope is created for it.

The following functions and objects are available to all event scripts.

ctx #

The context of the request. This object contains everything from the request (request, response, body, headers, etc...):

// Example:
if (ctx && ctx.req && ctx.req.headers && ctx.req.headers.host !== '192.168.178.34:2403') {
  cancel("You are not authorized to do that", 401);
}

The entire object is available as a gist here.

me #

The current user if one exists on the current Context.

isMe() #

isMe(id)

Returns true if the current user (me) matches the provided id.

this #

If the resource does not implement a custom domain, this will be an empty object. Otherwise this usually refers to the current domain's instance (eg. an object in a collection).

cancel() #

cancel(message, [statusCode])

Stops the current request with the provided error message and HTTP status code. Status code defaults to 400.

cancelIf(), cancelUnless() #

cancelIf(condition, message, [statusCode])
cancelUnless(condition, message, [statusCode])

Calls cancel(message, statusCode) if the provided condition is truthy (for cancelIf()) or falsy (for cancelUnless).

internal #

A boolean property, true if this request has been initiated by another script.

isRoot #

A boolean property, true if this request is authenticated as root (from the dashboard or a custom script).

query #

The current HTTP query. (eg ?foo=bar - query would be {foo: 'bar'}).

emit() #

emit([userCollection, query], message, [data])

Emits a realtime message to the client. You can use userCollection and query parameters to limit the message broadcast to specific users.

console #

Support for console.log() and other console methods.

More