documentation/handlers.md
### Creating Custom Handlers
Handlers represent the mechanism that backs a resource. Each handler is an object expected to provide:
* a constructor with an option parameter that can be used to inject any required handler specific configuration.
* a `ready` property indicating the handler is ready to process requests.
* some of the following methods:
* `initialise` - when jsonapi-server loads, this is invoked once for every resource using this handler. Its an opportunity to allocate memory, connect to databases, etc.
* `close` - for cleaning up upon `jsonApi.close()` (optional)
* `search` - for searching for resources that match some vague parameters.
* `find` - for finding a specific resource by id.
* `create` - for creating a new instance of a resource.
* `delete` - for deleting an existing resource.
* `update` - for updating an existing resource.
Failure to provide the above handler functions will result in `EFORBIDDEN` HTTP errors if the corresponding REST routes are requested.
#### The `rawResource` Format
All data stored behind handlers should be stored in a developer-friendly format with both attributes and relations mingled together:
```javascript
{
id: "aab14844-97e7-401c-98c8-0bd5ec922d93",
type: "photos",
title: "Matrix Code",
url: "http://www.example.com/foobar",
photographer: { type: "people", id: "ad3aa89e-9c5b-4ac9-a652-6670f9f27587" }
}
```
In the above example the `photographer` attribute is defined as relation to a resource of type `people`. jsonapi-server will deal with shuffling around and separating those attributes and relations when it needs to. Keep It Simple.
#### The `request` Format
All requests are presented to handlers in the following format:
```javascript
{
params: {
// All request parameters get combined into this object. Query params, body params, etc.
foo: "bar"
},
headers: {
// All HTTP request headers
host: "localhost:16006",
connection: "keep-alive"
},
route: {
// Routing information
host: "localhost:16006",
path: "/v1/swagger.json",
query: "foo=bar&baz=1",
combined: "https://localhost:16006/v1/swagger.json"
}
}
```
#### The `error` Format
All errors should be provided in the following format:
```javascript
{
// The desired HTTP code
status: "404",
// A very short identifier for this error
code: "ENOTFOUND",
// A short human readable description
title: "Requested resource does not exist",
// Some detail to assist debugging
detail: "There is no "+request.params.type+" with id "+request.params.id
}
```
#### constructor
The handler object constructor can, depending on the handler's requirements, expect a object parameter which will contain any properties required for configuring the handler. For example if the handler uses a database for persistence the configuration object will contain the properties required to connect to the database.
#### ready
The `ready` property should be set to a _truthy_ value once the handler is ready to process requests (which will usually happen at the end of `initialise`). If the handler is temporarily unable to process requests this property should be set to a _falsy_ value during the down period.
#### initialise
`initialise` is invoked with the `resourceConfig` of each resource using this handler.
```javascript
function(resourceConfig) { };
```
`resourceConfig` is the complete configuration object passed in to `jsonApi.define()`.
#### close
`close` is invoked without any parameters, when `jsonApi.close()` is called.
It should close database connections, file handles, timers, event listeners, etc, as though `initialise` were never called.
#### search
`search` is invoked with a `request` object (see above).
```javascript
function(request, callback) { };
```
the `callback` should be invoked with with an `error` or `null, [ rawResource ]`.
`search` needs to watch for any `request.params.relationships` parameters, they represent foreign key lookups. An example of this:
```
request.params.relationships = {
user: "ad3aa89e-9c5b-4ac9-a652-6670f9f27587"
}
```
translates to "Find me all of the resources whose user attribute is a link to a resource with id == ad3aa89e-9c5b-4ac9-a652-6670f9f27587".
#### find
`find` is invoked with a `request` object (see above).
```
function(request, callback) { };
```
the `callback` should be invoked with with an `error` or `null, rawResource`.
#### create
`create` is invoked with a `request` object (see above) AND a `newResource` object which is an instance of `rawResource` representing a validated instance of type `request.params.type`. The `newResource` will already have an `id` and is ready to be stored as per the resource definition.
```
function(request, newResource, callback) { };
```
the `callback` should be invoked with with an `error` or `newResource`.
#### delete
`delete` is invoked with a `request` object (see above). It should delete the resource of type `request.params.type` and id `request.params.id`.
```
function(request, callback) { };
```
the `callback` should be invoked with with an `error` or `null`.
#### update
`update` is invoked with a `request` object (see above) and a `partialResource` which represents a partial instance of `rawResource` - the properties of `rawResource` need to be merged over the original resource and saved.
```
function(request, partialResource, callback) { };
```
the `callback` should be invoked with with an `error` or `null, newUpdatedResource`.