Decorations
Overview
Decorations in Supercharge describe custom functionality extending the HTTP core. You’re essentially adding your own properties or methods to the core. It’s a controlled and safe way to extend three core objects in your application:
server
: the HTTP server instancerequest
: a request instance in a lifecycle methodtoolkit
: the response toolkit, also known as(h)
Where to Add Decorations
Plugins are a good place to add decorations. Adding a new decoration requires the server instance and plugins expose it.
Create a Decoration
A decoration can be a function or any other value, like an object, string, boolean, number or anything else.
A new decoration has this format:
server.decorate(type, property, method)
type
: the decorating interface (request
,toolkit
,server
)property
: the decoration’s namemethod
: the decoration’s function or value
Let’s look at some examples to illustrate the usage.
Example 1: Function Decoration
Imagine an application where you often need to check whether a resource exists. In case it isn’t available, you’ll render a 404 page. This is a typical reply: h.view('errors/404').code(404)
.
Using decorations, you can create a dedicated method to reply a 404 error view. You can centralize the reference to the error view and status code in a single place.
Here’s what a 404 decoration on the toolkit
can look like:
module.exports = {
name: 'decorate-404-quickshot',
register: (server) => {
async function render404() {
return this.view('errors/404').code(404)
}
server.decorate('toolkit', 'notFound', render404)
}
}
Please notice that the this
context in your decoration methods binds to the decorated object. Here, this
binds to the toolkit
and it’s methods. That’s the reason you can create a response from the toolkit decoration.
Go ahead and use the decoration in your application. Here’s an example of a route handler for this documentation searching for the requested page. In case the page isn’t available, the 404 response is a quick call to the decorated method:
handler: (request, h) => {
const page = await docs.getPageContent(request.params.page)
if (!page) {
return h.notFound()
}
return h.view('docs/page', { page })
}
The benefit here is that you compose a repeated response once and use it throughout your app.
Example 2: Object Decoration
This example illustrates how to decorate the server
instance with the app
property. The app
property is an object including details about your application. Here’s what a decoration may look like:
const { version } = require('../package.json')
module.exports = {
name: 'decorate-request-docs',
register: (server) => {
server.decorate('server', 'app', { version })
}
Throughout your application, you can use your decoration by accessing server.app.version
. In lifecycle methods (request handler, middleware), you may access the decorated object via request.server.app.version
.