siren-writer v0.5.0
node-siren-writer
A generator for siren hypermedia API responses.
Example
var writer = require('siren-writer');
var siren = writer('http://api.x.io');
var entity = siren({
class: 'order',
properties: {
orderNumber: 42,
itemCount: 3,
status: 'pending'
},
entities: [
{
class: [ 'items', 'collection' ],
rel: 'http://x.io/rels/order-items',
href: 'orders/42/items'
},
{
class: [ 'info', 'customer' ],
rel: 'http://x.io/rels/customer',
properties: {
customerId: 'pj123',
name: 'Peter Joseph'
},
links: {
rel: 'self',
href: 'customers/pj123'
}
}
],
actions: {
name: 'add-item',
title: 'Add Item',
method: 'POST',
href: 'orders/42/items',
type: 'application/x-www-form-urlencoded',
fields: [
{ name: 'orderNumber', type: 'hidden', value: '42' },
{ name: 'productCode', type: 'text' },
{ name: 'quantity', type: 'number' }
]
},
links: [
{
rel: 'self',
href: 'orders/42'
},
{
rel: 'previous',
href: 'orders/41'
},
{
rel: 'next',
href: 'orders/43'
}
]
});
console.log(entity);will produce the example from the Siren homepage:
{
"class": [ "order" ],
"properties": {
"orderNumber": 42,
"itemCount": 3,
"status": "pending"
},
"entities": [
{
"class": [ "items", "collection" ],
"rel": [ "http://x.io/rels/order-items" ],
"href": "http://api.x.io/orders/42/items"
},
{
"class": [ "info", "customer" ],
"rel": [ "http://x.io/rels/customer" ],
"properties": {
"customerId": "pj123",
"name": "Peter Joseph"
},
"links": [
{ "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
]
}
],
"actions": [
{
"name": "add-item",
"title": "Add Item",
"method": "POST",
"href": "http://api.x.io/orders/42/items",
"type": "application/x-www-form-urlencoded",
"fields": [
{ "name": "orderNumber", "type": "hidden", "value": "42" },
{ "name": "productCode", "type": "text" },
{ "name": "quantity", "type": "number" }
]
}
],
"links": [
{ "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
{ "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
{ "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
]
}API
writer(base)
Creates a new siren writer with the given base as the base URL for things
like rel and href throughout an entity.
siren(options)
The returned function is the entire API. It returns an object that can be serialized as a JSON response.
// express
res.json(siren(/* options */));
// koa
this.body = siren(/* options */);Generally-speaking, this API avoids performing magic. It wants you to be explicit, only accepting objects instead of positional arguments. However, there are a few ways that this API improves upon generating the response entirely from scratch:
- ensures that single values are converted into arrays where they're required
(eg:
class,rel, etc) - flattens nested arrays into a single array, particularly for things like
entitieswhere you could be merging several different types for a single response - automatically resolves URLs relative to the
baseURL (eg:hrefand anyrelvalues that aren't defined by IANA) - throws errors when you are missing things that are explicitly required, such
as the
hreforrelfor a link
The keys in options include everything in the spec,
so use that as a reference when building your configuration options. Additional properties will be included, but their behavior with clients cannot be guaranteed. Some other
things to be aware of:
- as mentioned before, don't be too concerned with arrays if you're only setting a single value
- don't be afraid to nest arrays, they will be flattened
- include the trailing
/in yourbase, especially when using a pathname - avoid using a leading
/in your relative URLs, as it will behave unexpectedly if yourbasehas a pathname as part of it. (ie:http://example.com/api/) - this library will
throwexceptions in the cases mentioned previously