UNPKG

5.81 kBMarkdownView Raw
1<h1 align="center">Fastify</h1>
2
3## Decorators
4
5If you need to add functionality to the Fastify instance, the `decorate` API is what you need.
6
7The API allows you to add new properties to the Fastify instance. A value is not restricted to a function and could also be an object or a string, for example.
8
9<a name="usage"></a>
10### Usage
11<a name="decorate"></a>
12**decorate**
13Just call the `decorate` API and pass the name of the new property and its value.
14```js
15fastify.decorate('utility', () => {
16 // something very useful
17})
18```
19
20As said above, you can also decorate the instance with non-function values:
21```js
22fastify.decorate('conf', {
23 db: 'some.db',
24 port: 3000
25})
26```
27
28Once you decorate the instance, you can access the value by using the name you passed as a parameter:
29```js
30fastify.utility()
31
32console.log(fastify.conf.db)
33```
34
35<a name="decorate-reply"></a>
36**decorateReply**
37As the name suggests, this API is needed if you want to add new methods to the `Reply` core object. Just call the `decorateReply` API and pass the name of the new property and its value:
38```js
39fastify.decorateReply('utility', function () {
40 // something very useful
41})
42```
43
44Note: using an arrow function will break the binding of `this` to the Fastify `reply` instance.
45
46<a name="decorate-request"></a>
47**decorateRequest**
48As above, this API is needed if you want to add new methods to the `Request` core object. Just call the `decorateRequest` API and pass the name of the new property and its value:
49```js
50fastify.decorateRequest('utility', function () {
51 // something very useful
52})
53```
54
55Note: using an arrow function will break the binding of `this` to the Fastify `request` instance.
56
57<a name="decorators-encapsulation"></a>
58#### Decorators and encapsulation
59
60If you define a decorator (using decorate, decorateRequest or decorateReply) with the same name more than once in the same **encapsulated** plugin, fastify will throw an exception.
61
62As an example, the following will throw:
63
64```js
65const server = require('fastify')()
66
67server.decorateReply('view', function (template, args) {
68 // Amazing view rendering engine.
69})
70
71server.get('/', (req, reply) => {
72 reply.view('/index.html', { hello: 'world' })
73})
74
75// Somewhere else in our codebase, we define another
76// view decorator. This throws.
77server.decorateReply('view', function (template, args) {
78 // another rendering engine
79})
80
81server.listen(3000)
82```
83
84
85But this will not:
86
87```js
88const server = require('fastify')()
89
90server.decorateReply('view', function (template, args) {
91 // Amazing view rendering engine.
92})
93
94server.register(async function (server, opts) {
95 // We add a view decorator to the current encapsulated
96 // plugin. This will not throw as outside of this encapsulated
97 // plugin view is the old one, while inside it is the new one.
98 server.decorateReply('view', function (template, args) {
99 // another rendering engine
100 })
101
102 server.get('/', (req, reply) => {
103 reply.view('/index.page', { hello: 'world' })
104 })
105}, { prefix: '/bar' })
106
107server.listen(3000)
108```
109
110<a name="getters-setters"></a>
111#### Getters and Setters
112
113Decorators accept special "getter/setter" objects. These objects have functions named `getter` and `setter` (though, the `setter` function is optional). This allows defining properties via decorators. For example:
114
115```js
116fastify.decorate('foo', {
117 getter () {
118 return 'a getter'
119 }
120})
121```
122
123Will define the `foo` property on the *Fastify* instance:
124
125```js
126console.log(fastify.foo) // 'a getter'
127```
128
129<a name="usage_notes"></a>
130#### Usage Notes
131`decorateReply` and `decorateRequest` are used to modify the `Reply` and `Request` constructors respectively by adding methods or properties. To update these properties you should directly access the desired property of the `Reply` or `Request` object.
132
133As an example let's add a user property to the `Request` object:
134
135```js
136// Decorate request with a 'user' property
137fastify.decorateRequest('user', '')
138
139// Update our property
140fastify.addHook('preHandler', (req, reply, next) => {
141 req.user = 'Bob Dylan'
142 next()
143})
144// And finally access it
145fastify.get('/', (req, reply) => {
146 reply.send(`Hello ${req.user}!`)
147})
148```
149Note: The usage of `decorateReply` and `decorateRequest` is optional in this case but will allow Fastify to optimize for performance.
150
151<a name="sync-async"></a>
152#### Sync and Async
153`decorate` is a *synchronous* API. If you need to add a decorator that has an *asynchronous* bootstrap, Fastify could boot up before your decorator is ready. To avoid this issue, you must use the `register` API in combination with `fastify-plugin`. To learn more, check out the [Plugins](https://github.com/fastify/fastify/blob/master/docs/Plugins.md) documentation as well.
154
155<a name="dependencies"></a>
156#### Dependencies
157If your decorator depends on another decorator, you can easily declare the other decorator as a dependency. You just need to add an array of strings (representing the names of the decorators on which yours depends) as the third parameter:
158```js
159fastify.decorate('utility', fn, ['greet', 'log'])
160```
161
162If a dependency is not satisfied, `decorate` will throw an exception, but don't worry: the dependency check is executed before the server boots up, so it won't ever happen at runtime.
163
164<a name="has-decorator"></a>
165#### hasDecorator
166You can check for the presence of a decorator with the `hasDecorator` API:
167```js
168fastify.hasDecorator('utility')
169```
170
171<a name="has-request-decorator"></a>
172#### hasRequestDecorator
173You can check for the presence of a Request decorator with the `hasRequestDecorator` API:
174```js
175fastify.hasRequestDecorator('utility')
176```
177
178<a name="has-reply-decorator"></a>
179#### hasReplyDecorator
180You can check for the presence of a Reply decorator with the `hasReplyDecorator` API:
181```js
182fastify.hasReplyDecorator('utility')
183```