fastify 3.11.0 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
  [![NPM downloads](https://img.shields.io/npm/dm/fastify.svg?style=flat)](https://www.npmjs.com/package/fastify)
20
20
  [![Security Responsible
21
21
  Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md)
22
- [![Discord](https://img.shields.io/discord/725613461949906985)](https://discord.gg/D3FZYPy)
22
+ [![Discord](https://img.shields.io/discord/725613461949906985)](https://discord.gg/fastify)
23
23
 
24
24
  </div>
25
25
 
@@ -216,10 +216,12 @@ Team members are listed in alphabetical order.
216
216
  ### Fastify Core team
217
217
  * [__Tommaso Allevi__](https://github.com/allevo), <https://twitter.com/allevitommaso>, <https://www.npmjs.com/~allevo>
218
218
  * [__Ethan Arrowood__](https://github.com/Ethan-Arrowood/), <https://twitter.com/arrowoodtech>, <https://www.npmjs.com/~ethan_arrowood>
219
+ * [__Harry Brundage__](https://github.com/airhorns/), <https://twitter.com/harrybrundage>, <https://www.npmjs.com/~airhorns>
219
220
  * [__David Mark Clements__](https://github.com/davidmarkclements), <https://twitter.com/davidmarkclem>, <https://www.npmjs.com/~davidmarkclements>
220
221
  * [__Matteo Collina__](https://github.com/mcollina), <https://twitter.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
221
222
  * [__Tomas Della Vedova__](https://github.com/delvedor), <https://twitter.com/delvedor>, <https://www.npmjs.com/~delvedor>
222
223
  * [__Dustin Deus__](https://github.com/StarpTech), <https://twitter.com/dustindeus>, <https://www.npmjs.com/~starptech>
224
+ * [__Ayoub El Khattabi__](https://github.com/AyoubElk), <https://twitter.com/ayoubelkh>, <https://www.npmjs.com/~ayoubelk>
223
225
  * [__Denis Fäcke__](https://github.com/SerayaEryn), <https://twitter.com/serayaeryn>, <https://www.npmjs.com/~serayaeryn>
224
226
  * [__Rafael Gonzaga__](https://github.com/rafaelgss), <https://twitter.com/_rafaelgss>, <https://www.npmjs.com/~rafaelgss>
225
227
  * [__Vincent Le Goff__](https://github.com/zekth)
@@ -230,7 +232,9 @@ Team members are listed in alphabetical order.
230
232
 
231
233
  ### Fastify Plugins team
232
234
  * [__Matteo Collina__](https://github.com/mcollina), <https://twitter.com/matteocollina>, <https://www.npmjs.com/~matteo.collina>
235
+ * [__Harry Brundage__](https://github.com/airhorns/), <https://twitter.com/harrybrundage>, <https://www.npmjs.com/~airhorns>
233
236
  * [__Tomas Della Vedova__](https://github.com/delvedor), <https://twitter.com/delvedor>, <https://www.npmjs.com/~delvedor>
237
+ * [__Ayoub El Khattabi__](https://github.com/AyoubElk), <https://twitter.com/ayoubelkh>, <https://www.npmjs.com/~ayoubelk>
234
238
  * [__Vincent Le Goff__](https://github.com/zekth)
235
239
  * [__Salman Mitha__](https://github.com/salmanm), <https://www.npmjs.com/~salmanm>
236
240
  * [__Maksim Sinik__](https://github.com/fox1t), <https://twitter.com/maksimsinik>, <https://www.npmjs.com/~fox1t>
package/docs/Ecosystem.md CHANGED
@@ -44,7 +44,7 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
44
44
  - [`fastify-schedule`](https://github.com/fastify/fastify-schedule) Plugin for scheduling periodic jobs, based on [toad-scheduler](https://github.com/kibertoad/toad-scheduler).
45
45
  - [`fastify-sensible`](https://github.com/fastify/fastify-sensible) Defaults for Fastify that everyone can agree on. It adds some useful decorators such as http errors and assertions, but also more request and reply methods.
46
46
  - [`fastify-static`](https://github.com/fastify/fastify-static) Plugin for serving static files as fast as possible.
47
- - [`fastify-swagger`](https://github.com/fastify/fastify-swagger) Swagger documentation generator for Fastify.
47
+ - [`fastify-swagger`](https://github.com/fastify/fastify-swagger) Plugin for serving Swagger/OpenAPI documentation for Fastify, supporting dynamic generation.
48
48
  - [`fastify-websocket`](https://github.com/fastify/fastify-websocket) WebSocket support for Fastify. Built upon [websocket-stream](https://github.com/maxogden/websocket-stream).
49
49
  - [`fastify-url-data`](https://github.com/fastify/fastify-url-data) Decorate the `Request` object with a method to access raw URL components.
50
50
  - [`point-of-view`](https://github.com/fastify/point-of-view) Templates rendering (_ejs, pug, handlebars, marko_) plugin support for Fastify.
@@ -124,6 +124,7 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
124
124
  - [`fastify-nodemailer`](https://github.com/lependu/fastify-nodemailer) Plugin to share [nodemailer](https://nodemailer.com) transporter across Fastify.
125
125
  - [`fastify-normalize-request-reply`](https://github.com/ericrglass/fastify-normalize-request-reply) Plugin to normalize the request and reply to the Express version 4.x request and response, which allows use of middleware, like swagger-stats, that was originally written for Express.
126
126
  - [`fastify-now`](https://github.com/yonathan06/fastify-now) Structure your endpoints in a folder and load them dynamically with fastify
127
+ - [`fastify-nuxtjs`](https://github.com/gomah/fastify-nuxtjs) Vue server side rendering support for Fastify with Nuxt.js Framework.
127
128
  - [`fastify-oas`](https://gitlab.com/m03geek/fastify-oas) Generates OpenAPI 3.0+ documentation from routes schemas for Fastify.
128
129
  - [`fastify-objectionjs`](https://github.com/jarcodallo/fastify-objectionjs) Plugin for the `fastify` framework that provides integration with objectionjs ORM.
129
130
  - [`fastify-objectionjs-classes`](https://github.com/kamikazechaser/fastify-objectionjs-classes) Plugin to cherry pick classes from objectionjs ORM.
@@ -52,7 +52,9 @@ fastify.register(async function authenticatedContext (childServer) {
52
52
  handler (request, response) {
53
53
  response.send({
54
54
  answer: request.answer,
55
+ // request.foo will be undefined as it's only defined in publicContext
55
56
  foo: request.foo,
57
+ // request.bar will be undefined as it's only defined in grandchildContext
56
58
  bar: request.bar
57
59
  })
58
60
  }
@@ -69,6 +71,7 @@ fastify.register(async function publicContext (childServer) {
69
71
  response.send({
70
72
  answer: request.answer,
71
73
  foo: request.foo,
74
+ // request.bar will be undefined as it's only defined in grandchildContext
72
75
  bar: request.bar
73
76
  })
74
77
  }
package/docs/Hooks.md CHANGED
@@ -456,7 +456,7 @@ Warn: if you declare the function with an [arrow function](https://developer.moz
456
456
  <a name="route-hooks"></a>
457
457
 
458
458
  ## Route level hooks
459
- You can declare one or more custom [onRequest](#onrequest), [onResponse](#onresponse), [preParsing](#preparsing), [preValidation](#prevalidation), [preHandler](#prehandler) and [preSerialization](#preserialization) hook(s) that will be **unique** for the route.
459
+ You can declare one or more custom lifecycle hooks ([onRequest](#onrequest), [onResponse](#onresponse), [preParsing](#preparsing), [preValidation](#prevalidation), [preHandler](#prehandler), [preSerialization](#preserialization), [onSend](#onsend), [onTimeout](#ontimeout), and [onError](#onerror)) hook(s) that will be **unique** for the route.
460
460
  If you do so, those hooks are always executed as the last hook in their category. <br/>
461
461
  This can be useful if you need to implement authentication, where the [preParsing](#preparsing) or [preValidation](#prevalidation) hooks are exactly what you need.
462
462
  Multiple route-level hooks can also be specified as an array.
@@ -492,6 +492,21 @@ fastify.addHook('preSerialization', (request, reply, payload, done) => {
492
492
  done(null, payload)
493
493
  })
494
494
 
495
+ fastify.addHook('onSend', (request, reply, payload, done) => {
496
+ // Your code
497
+ done(null, payload)
498
+ })
499
+
500
+ fastify.addHook('onTimeout', (request, reply, done) => {
501
+ // Your code
502
+ done()
503
+ })
504
+
505
+ fastify.addHook('onError', (request, reply, error, done) => {
506
+ // Your code
507
+ done()
508
+ })
509
+
495
510
  fastify.route({
496
511
  method: 'GET',
497
512
  url: '/',
@@ -526,6 +541,18 @@ fastify.route({
526
541
  // This hook will always be executed after the shared `preSerialization` hooks
527
542
  done(null, payload)
528
543
  },
544
+ onSend: (request, reply, payload, done) => {
545
+ // This hook will always be executed after the shared `onSend` hooks
546
+ done(null, payload)
547
+ },
548
+ onTimeout: (request, reply, done) => {
549
+ // This hook will always be executed after the shared `onTimeout` hooks
550
+ done()
551
+ },
552
+ onError: (request, reply, error, done) => {
553
+ // This hook will always be executed after the shared `onError` hooks
554
+ done()
555
+ },
529
556
  handler: function (request, reply) {
530
557
  reply.send({ hello: 'world' })
531
558
  }
package/docs/Reply.md CHANGED
@@ -224,7 +224,7 @@ app.get('/cookie-2', (req, reply) => {
224
224
  reply.raw.end()
225
225
  })
226
226
  ```
227
- Another example of the misuse of `Reply.raw` is explained in [Reply.md#getheaders](Reply.md#getheaders).
227
+ Another example of the misuse of `Reply.raw` is explained in [Reply](Reply.md#getheaders).
228
228
 
229
229
  <a name="sent"></a>
230
230
  ### .sent
package/docs/Server.md CHANGED
@@ -133,8 +133,6 @@ logger will point to this instance.
133
133
  + `object`: a standard Pino [options object](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor).
134
134
  This will be passed directly to the Pino constructor. If the following properties
135
135
  are not present on the object, they will be added accordingly:
136
- * `genReqId`: a synchronous function that will be used to generate identifiers
137
- for incoming requests. The default function generates sequential identifiers.
138
136
  * `level`: the minimum logging level. If not set, it will be set to `'info'`.
139
137
  * `serializers`: a hash of serialization functions. By default, serializers
140
138
  are added for `req` (incoming request objects), `res` (outgoing response
@@ -840,6 +838,47 @@ The input `schema` can access all the shared schemas added with [`.addSchema`](#
840
838
  #### schemaErrorFormatter
841
839
  This property can be used set a function to format errors that happen while the `validationCompiler` fails to validate the schema. See [#error-handling](Validation-and-Serialization.md#schemaerrorformatter).
842
840
 
841
+ <a name="schema-controller"></a>
842
+ #### schemaController
843
+ This property can be used to fully manage where the schemas of your application will be stored.
844
+ It can be useful when your schemas are stored in another data structure that is unknown to Fastify.
845
+ See [issue #2446](https://github.com/fastify/fastify/issues/2446) for an example of what
846
+ this property helps to resolve.
847
+
848
+ ```js
849
+ const fastify = Fastify({
850
+ schemaController: {
851
+ /**
852
+ * This factory is called whenever `fastify.register()` is called.
853
+ * It may receive as input the schemas of the parent context if some schemas has been added.
854
+ * @param {object} parentSchemas these schemas will be returned by the `getSchemas()` method function of the returned `bucket`.
855
+ */
856
+ bucket: function factory (parentSchemas) {
857
+ return {
858
+ addSchema (inputSchema) {
859
+ // This function must store the schema added by the user.
860
+ // This function is invoked when `fastify.addSchema()` is called.
861
+ },
862
+ getSchema (schema$id) {
863
+ // This function must return the raw schema requested by the `schema$id`.
864
+ // This function is invoked when `fastify.getSchema(id)` is called.
865
+ return aSchema
866
+ },
867
+ getSchemas () {
868
+ // This function must return all the schemas referenced by the routes schemas' $ref
869
+ // It must return a JSON where the property is the schema `$id` and the value is the raw JSON Schema.
870
+ const allTheSchemaStored = {
871
+ 'schema$id1': schema1,
872
+ 'schema$id2': schema2
873
+ }
874
+ return allTheSchemaStored
875
+ }
876
+ }
877
+ }
878
+ }
879
+ });
880
+ ```
881
+
843
882
  <a name="set-not-found-handler"></a>
844
883
  #### setNotFoundHandler
845
884
 
@@ -279,69 +279,41 @@ Then it should work fine
279
279
 
280
280
  [Vercel](https://vercel.com) provides zero configuration deployment for
281
281
  Node.js applications. In order to use now, it is as simple as
282
- configuring your `now.json` file like the following:
282
+ configuring your `vercel.json` file like the following:
283
283
 
284
284
  ```json
285
285
  {
286
- "version": 2,
287
- "builds": [
288
- {
289
- "src": "api/serverless.js",
290
- "use": "@now/node",
291
- "config": {
292
- "helpers": false
293
- }
294
- }
295
- ],
296
- "routes": [
297
- { "src": "/.*", "dest": "/api/serverless.js"}
298
- ]
286
+ "rewrites": [
287
+ {
288
+ "source": "/(.*)",
289
+ "destination": "/api/serverless.js"
290
+ }
291
+ ]
299
292
  }
300
293
  ```
301
294
 
302
295
  Then, write a `api/serverless.js` like so:
303
296
 
304
297
  ```js
305
- 'use strict'
298
+ "use strict";
306
299
 
307
- const build = require('./index')
300
+ // Read the .env file.
301
+ import * as dotenv from "dotenv";
302
+ dotenv.config();
308
303
 
309
- const app = build()
310
-
311
- module.exports = async function (req, res) {
312
- await app.ready()
313
- app.server.emit('request', req, res)
314
- }
315
- ```
316
-
317
- And a `api/index.js` file:
318
-
319
- ```js
320
- 'use strict'
304
+ // Require the framework
305
+ import Fastify from "fastify";
321
306
 
322
- const fastify = require('fastify')
307
+ // Instantiate Fastify with some config
308
+ const app = Fastify({
309
+ logger: true,
310
+ });
323
311
 
324
- function build () {
325
- const app = fastify({
326
- logger: true
327
- })
312
+ // Register your application as a normal plugin.
313
+ app.register(import("../src/app"));
328
314
 
329
- app.get('/', async (req, res) => {
330
- const { name = 'World' } = req.query
331
- req.log.info({ name }, 'hello world!')
332
- return `Hello ${name}!`
333
- })
334
-
335
- return app
315
+ export default async (req, res) => {
316
+ await app.ready();
317
+ app.server.emit('request', req, res);
336
318
  }
337
-
338
- module.exports = build
339
- ```
340
-
341
- Note that you'll need to use Node 10 by setting it in `package.json`:
342
-
343
- ```js
344
- "engines": {
345
- "node": "10.x"
346
- },
347
319
  ```
@@ -37,7 +37,7 @@ This example will get you up and running with Fastify and TypeScript. It results
37
37
  ```
38
38
  3. Initialize a TypeScript configuration file:
39
39
  ```bash
40
- npx typescript --init
40
+ npx tsc --init
41
41
  ```
42
42
  or use one of the [recommended ones](https://github.com/tsconfig/bases#node-10-tsconfigjson).
43
43
 
@@ -82,7 +82,7 @@ The type system heavily relies on generic properties to provide the most accurat
82
82
  }
83
83
 
84
84
  interface IHeaders {
85
- 'H-Custom': string;
85
+ 'h-Custom': string;
86
86
  }
87
87
  ```
88
88
  3. Using the two interfaces, define a new API route and pass them as generics. The shorthand route methods (i.e. `.get`) accept a generic object `RequestGenericInterface` containing four named properties: `Body`, `Querystring`, `Params`, and `Headers`. The interfaces will be passed down through the route method into the route method handler `request` instance.
@@ -92,7 +92,7 @@ The type system heavily relies on generic properties to provide the most accurat
92
92
  Headers: IHeaders
93
93
  }>('/auth', async (request, reply) => {
94
94
  const { username, password } = request.query
95
- const customerHeader = request.headers['H-Custom']
95
+ const customerHeader = request.headers['h-Custom']
96
96
  // do something with request data
97
97
 
98
98
  return `logged in!`
@@ -115,7 +115,7 @@ The type system heavily relies on generic properties to provide the most accurat
115
115
  done(username !== 'admin' ? new Error('Must be admin') : undefined) // only validate `admin` account
116
116
  }
117
117
  }, async (request, reply) => {
118
- const customerHeader = request.headers['H-Custom']
118
+ const customerHeader = request.headers['h-Custom']
119
119
  // do something with request data
120
120
  return `logged in!`
121
121
  })
@@ -139,10 +139,10 @@ In the last example we used interfaces to define the types for the request query
139
139
  "title": "Headers Schema",
140
140
  "type": "object",
141
141
  "properties": {
142
- "H-Custom": { "type": "string" }
142
+ "h-Custom": { "type": "string" }
143
143
  },
144
144
  "additionalProperties": false,
145
- "required": ["H-Custom"]
145
+ "required": ["h-Custom"]
146
146
  }
147
147
  ```
148
148
  ```json
@@ -194,7 +194,7 @@ In the last example we used interfaces to define the types for the request query
194
194
  done(username !== 'admin' ? new Error('Must be admin') : undefined)
195
195
  }
196
196
  }, async (request, reply) => {
197
- const customerHeader = request.headers['H-Custom']
197
+ const customerHeader = request.headers['h-Custom']
198
198
  // do something with request data
199
199
  return `logged in!`
200
200
  })
@@ -211,11 +211,11 @@ In the last example we used interfaces to define the types for the request query
211
211
  },
212
212
  preHandler: (request, reply) => {
213
213
  const { username, password } = request.query
214
- const customerHeader = request.headers['H-Custom']
214
+ const customerHeader = request.headers['h-Custom']
215
215
  },
216
216
  handler: (request, reply) => {
217
217
  const { username, password } = request.query
218
- const customerHeader = request.headers['H-Custom']
218
+ const customerHeader = request.headers['h-Custom']
219
219
  }
220
220
  })
221
221
 
@@ -393,6 +393,23 @@ However, there are a couple of suggestions to help improve this experience:
393
393
  - Make sure the `no-unused-vars` rule is enabled in [ESLint](https://eslint.org/docs/rules/no-unused-vars) and any imported plugin are actually being loaded.
394
394
  - Use a module such as [depcheck](https://www.npmjs.com/package/depcheck) or [npm-check](https://www.npmjs.com/package/npm-check) to verify plugin dependencies are being used somewhere in your project.
395
395
 
396
+ ## Code Completion In Vanilla JavaScript
397
+
398
+ Vanilla JavaScript can use the published types to provide code completion (e.g. [Intellisense](https://code.visualstudio.com/docs/editor/intellisense)) by following the [TypeScript JSDoc Reference](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).
399
+
400
+ For example:
401
+
402
+ ```js
403
+ /**
404
+ * setup some routes
405
+ * @param {import("fastify").FastifyInstance} fastify
406
+ * @param {*} opts
407
+ */
408
+ module.exports = async function (fastify, opts) {
409
+ fastify.get('/look', () => 'at me');
410
+ }
411
+ ```
412
+
396
413
  ## API Type System Documentation
397
414
 
398
415
  This section is a detailed account of all the types available to you in Fastify version 3.x
package/fastify.js CHANGED
@@ -15,9 +15,7 @@ const {
15
15
  kLogLevel,
16
16
  kLogSerializers,
17
17
  kHooks,
18
- kSchemas,
19
- kValidatorCompiler,
20
- kSerializerCompiler,
18
+ kSchemaController,
21
19
  kReplySerializerDefault,
22
20
  kContentTypeParser,
23
21
  kReply,
@@ -36,8 +34,8 @@ const Request = require('./lib/request')
36
34
  const supportedMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
37
35
  const decorator = require('./lib/decorate')
38
36
  const ContentTypeParser = require('./lib/contentTypeParser')
37
+ const SchemaController = require('./lib/schema-controller')
39
38
  const { Hooks, hookRunnerApplication } = require('./lib/hooks')
40
- const { Schemas } = require('./lib/schemas')
41
39
  const { createLogger } = require('./lib/logger')
42
40
  const pluginUtils = require('./lib/pluginUtils')
43
41
  const reqIdGenFactory = require('./lib/reqIdGenFactory')
@@ -86,6 +84,10 @@ function fastify (options) {
86
84
  throw new Error(`querystringParser option should be a function, instead got '${typeof options.querystringParser}'`)
87
85
  }
88
86
 
87
+ if (options.schemaController && options.schemaController.bucket && typeof options.schemaController.bucket !== 'function') {
88
+ throw new Error(`schemaController.bucket option should be a function, instead got '${typeof options.schemaController.bucket}'`)
89
+ }
90
+
89
91
  validateBodyLimitOption(options.bodyLimit)
90
92
 
91
93
  const requestIdHeader = options.requestIdHeader || defaultInitOptions.requestIdHeader
@@ -155,7 +157,7 @@ function fastify (options) {
155
157
  const { server, listen } = createServer(options, httpHandler)
156
158
 
157
159
  const setupResponseListeners = Reply.setupResponseListeners
158
- const schemas = new Schemas()
160
+ const schemaController = SchemaController.buildSchemaController(null, options.schemaController)
159
161
 
160
162
  // Public API
161
163
  const fastify = {
@@ -172,11 +174,9 @@ function fastify (options) {
172
174
  [kLogLevel]: '',
173
175
  [kLogSerializers]: null,
174
176
  [kHooks]: new Hooks(),
175
- [kSchemas]: schemas,
176
- [kValidatorCompiler]: null,
177
+ [kSchemaController]: schemaController,
177
178
  [kSchemaErrorFormatter]: null,
178
179
  [kErrorHandler]: defaultErrorHandler,
179
- [kSerializerCompiler]: null,
180
180
  [kReplySerializerDefault]: null,
181
181
  [kContentTypeParser]: new ContentTypeParser(
182
182
  bodyLimit,
@@ -230,10 +230,11 @@ function fastify (options) {
230
230
  addHook: addHook,
231
231
  // schemas
232
232
  addSchema: addSchema,
233
- getSchema: schemas.getSchema.bind(schemas),
234
- getSchemas: schemas.getSchemas.bind(schemas),
233
+ getSchema: schemaController.getSchema.bind(schemaController),
234
+ getSchemas: schemaController.getSchemas.bind(schemaController),
235
235
  setValidatorCompiler: setValidatorCompiler,
236
236
  setSerializerCompiler: setSerializerCompiler,
237
+ setSchemaController: setSchemaController,
237
238
  setReplySerializer: setReplySerializer,
238
239
  setSchemaErrorFormatter: setSchemaErrorFormatter,
239
240
  // custom parsers
@@ -281,10 +282,10 @@ function fastify (options) {
281
282
  get () { return this[kRoutePrefix] }
282
283
  },
283
284
  validatorCompiler: {
284
- get () { return this[kValidatorCompiler] }
285
+ get () { return this[kSchemaController].getValidatorCompiler() }
285
286
  },
286
287
  serializerCompiler: {
287
- get () { return this[kSerializerCompiler] }
288
+ get () { return this[kSchemaController].getSerializerCompiler() }
288
289
  },
289
290
  version: {
290
291
  get () {
@@ -495,7 +496,7 @@ function fastify (options) {
495
496
  // wrapper that we expose to the user for schemas handling
496
497
  function addSchema (schema) {
497
498
  throwIfAlreadyStarted('Cannot call "addSchema" when fastify instance is already started!')
498
- this[kSchemas].add(schema)
499
+ this[kSchemaController].add(schema)
499
500
  this[kChildren].forEach(child => child.addSchema(schema))
500
501
  return this
501
502
  }
@@ -562,7 +563,7 @@ function fastify (options) {
562
563
 
563
564
  function setValidatorCompiler (validatorCompiler) {
564
565
  throwIfAlreadyStarted('Cannot call "setValidatorCompiler" when fastify instance is already started!')
565
- this[kValidatorCompiler] = validatorCompiler
566
+ this[kSchemaController].setValidatorCompiler(validatorCompiler)
566
567
  return this
567
568
  }
568
569
 
@@ -575,7 +576,17 @@ function fastify (options) {
575
576
 
576
577
  function setSerializerCompiler (serializerCompiler) {
577
578
  throwIfAlreadyStarted('Cannot call "setSerializerCompiler" when fastify instance is already started!')
578
- this[kSerializerCompiler] = serializerCompiler
579
+ this[kSchemaController].setSerializerCompiler(serializerCompiler)
580
+ return this
581
+ }
582
+
583
+ function setSchemaController (schemaControllerOpts) {
584
+ throwIfAlreadyStarted('Cannot call "setSchemaController" when fastify instance is already started!')
585
+ const old = this[kSchemaController]
586
+ const schemaController = SchemaController.buildSchemaController(old.parent, Object.assign({}, old.opts, schemaControllerOpts))
587
+ this[kSchemaController] = schemaController
588
+ this.getSchema = schemaController.getSchema.bind(schemaController)
589
+ this.getSchemas = schemaController.getSchemas.bind(schemaController)
579
590
  return this
580
591
  }
581
592