A hapi plugin for a jsonapi style output to all requests. We are using the jsonapi standard with our own house rules where we have adapted the standard to suit our needs as a business.
If you want to work on this repo you will need to install the dependencies
$ npm install
plugin-jsonapi works as a plugin to a hapijs server and automatically extends the onPreResponse request lifecycle event. Once a request has left control of the handler we then layer the jsonapi sugar over the top to build any linked resources.
Jsonapi will look for 3 different properties in its response:
- Resource (what the client actually asked for)
- Meta (information about the resource e.g. pagination details)
- Linked resources (associated resources that were requested by the client in the form of
includes)
The plugin will build the href for all the linked resources, the minimum required is type. ex:
{
...
"linked": {
"faqs": [
"type": "faqs"
]
}
...
}
The plugin will build the href as:
{
...
"linked": {
"faqs": [
"type": "faqs",
"href": "/faqs/"
]
}
...
}
- Ids Ids is an array of strings, it can contain one or more strings
{
...
"linked": {
"faqs": [
"ids": ["ID1", "ID2"],
"type": "faqs"
]
}
...
}
The plugin will build the href as:
{
...
"linked": {
"faqs": [
"ids": ["ID1", "ID2"],
"type": "faqs",
"href": "/faqs/ID1,ID2"
]
}
...
}
- filter Filter is an object which allow add some query string parameters, this will be a key value pair. The key will be used for the filter and the value is an array of strings.
{
...
"linked": {
"faqs": [
"type": "faqs",
"filter": {
"productIds": ["ID1", "ID2"]
}
]
}
...
}
The plugin will build the href as:
{
...
"linked": {
"faqs": [
"type": "faqs",
"href": "/faqs/?filter%5BproductIds%5D=ID1,ID2"
]
}
...
}
You can combine ids and filter.
When configuring your handler function you MUST have a bind property and define the resourceName.
bind: {
resourceName: 'things' // always plural...
}
When replying with a result from a handler, a successful payload can include all 3 aforementioned properties (resource, meta and linked) but must have at least a resource. Note importantly that the resource is always placed at the root, meta and linked are namespaced off the root.
A fully fledged reply might be built something like this e.g.
/* here we are inside your handler, your logic goes before this */
var result = {};
// resource is always placed at the root of the result
result[this.resourceName] = resourceData; // `resourceData` must be an array of objects.
// meta is namespaced off the root and is optional
result.meta = {};
result.meta[this.resourceName] = {
currency: 'GBP'
}
// linked is also namespaced off the root and is optional
result.linked = {};
result.linked[this.resourceName] = [ {
linkedStuff: {} //more objects
} ]
reply( result );
Code is linted checked against the style guide with make-up, running npm test will run all tests required.
Copyright (c) 2016 Holiday Extras Licensed under the MIT license.