node-fastify 5.8.3

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.
Files changed (354) hide show
  1. package/.borp.yaml +3 -0
  2. package/.markdownlint-cli2.yaml +22 -0
  3. package/.prettierignore +1 -0
  4. package/GOVERNANCE.md +4 -0
  5. package/LICENSE +21 -0
  6. package/PROJECT_CHARTER.md +126 -0
  7. package/README.md +423 -0
  8. package/SECURITY.md +220 -0
  9. package/SPONSORS.md +24 -0
  10. package/build/build-error-serializer.js +35 -0
  11. package/build/build-validation.js +169 -0
  12. package/build/sync-version.js +11 -0
  13. package/docs/Guides/Benchmarking.md +60 -0
  14. package/docs/Guides/Database.md +321 -0
  15. package/docs/Guides/Delay-Accepting-Requests.md +608 -0
  16. package/docs/Guides/Detecting-When-Clients-Abort.md +172 -0
  17. package/docs/Guides/Ecosystem.md +726 -0
  18. package/docs/Guides/Fluent-Schema.md +127 -0
  19. package/docs/Guides/Getting-Started.md +620 -0
  20. package/docs/Guides/Index.md +43 -0
  21. package/docs/Guides/Migration-Guide-V3.md +287 -0
  22. package/docs/Guides/Migration-Guide-V4.md +267 -0
  23. package/docs/Guides/Migration-Guide-V5.md +727 -0
  24. package/docs/Guides/Plugins-Guide.md +520 -0
  25. package/docs/Guides/Prototype-Poisoning.md +383 -0
  26. package/docs/Guides/Recommendations.md +378 -0
  27. package/docs/Guides/Serverless.md +604 -0
  28. package/docs/Guides/Style-Guide.md +246 -0
  29. package/docs/Guides/Testing.md +481 -0
  30. package/docs/Guides/Write-Plugin.md +103 -0
  31. package/docs/Guides/Write-Type-Provider.md +34 -0
  32. package/docs/Reference/ContentTypeParser.md +271 -0
  33. package/docs/Reference/Decorators.md +436 -0
  34. package/docs/Reference/Encapsulation.md +194 -0
  35. package/docs/Reference/Errors.md +377 -0
  36. package/docs/Reference/HTTP2.md +94 -0
  37. package/docs/Reference/Hooks.md +958 -0
  38. package/docs/Reference/Index.md +73 -0
  39. package/docs/Reference/LTS.md +86 -0
  40. package/docs/Reference/Lifecycle.md +99 -0
  41. package/docs/Reference/Logging.md +268 -0
  42. package/docs/Reference/Middleware.md +79 -0
  43. package/docs/Reference/Plugins.md +245 -0
  44. package/docs/Reference/Principles.md +73 -0
  45. package/docs/Reference/Reply.md +1001 -0
  46. package/docs/Reference/Request.md +295 -0
  47. package/docs/Reference/Routes.md +802 -0
  48. package/docs/Reference/Server.md +2389 -0
  49. package/docs/Reference/Type-Providers.md +256 -0
  50. package/docs/Reference/TypeScript.md +1729 -0
  51. package/docs/Reference/Validation-and-Serialization.md +1130 -0
  52. package/docs/Reference/Warnings.md +58 -0
  53. package/docs/index.md +24 -0
  54. package/docs/resources/encapsulation_context.drawio +1 -0
  55. package/docs/resources/encapsulation_context.svg +3 -0
  56. package/eslint.config.js +35 -0
  57. package/examples/asyncawait.js +38 -0
  58. package/examples/benchmark/body.json +3 -0
  59. package/examples/benchmark/hooks-benchmark-async-await.js +44 -0
  60. package/examples/benchmark/hooks-benchmark.js +52 -0
  61. package/examples/benchmark/parser.js +47 -0
  62. package/examples/benchmark/simple.js +30 -0
  63. package/examples/benchmark/webstream.js +27 -0
  64. package/examples/hooks.js +91 -0
  65. package/examples/http2.js +39 -0
  66. package/examples/https.js +38 -0
  67. package/examples/parser.js +53 -0
  68. package/examples/plugin.js +12 -0
  69. package/examples/route-prefix.js +38 -0
  70. package/examples/shared-schema.js +38 -0
  71. package/examples/simple-stream.js +20 -0
  72. package/examples/simple.js +32 -0
  73. package/examples/simple.mjs +27 -0
  74. package/examples/typescript-server.ts +79 -0
  75. package/examples/use-plugin.js +29 -0
  76. package/fastify.d.ts +253 -0
  77. package/fastify.js +985 -0
  78. package/integration/server.js +29 -0
  79. package/integration/test.sh +23 -0
  80. package/lib/config-validator.js +1266 -0
  81. package/lib/content-type-parser.js +413 -0
  82. package/lib/content-type.js +160 -0
  83. package/lib/context.js +98 -0
  84. package/lib/decorate.js +152 -0
  85. package/lib/error-handler.js +173 -0
  86. package/lib/error-serializer.js +134 -0
  87. package/lib/error-status.js +14 -0
  88. package/lib/errors.js +516 -0
  89. package/lib/four-oh-four.js +190 -0
  90. package/lib/handle-request.js +195 -0
  91. package/lib/head-route.js +45 -0
  92. package/lib/hooks.js +429 -0
  93. package/lib/initial-config-validation.js +37 -0
  94. package/lib/logger-factory.js +136 -0
  95. package/lib/logger-pino.js +68 -0
  96. package/lib/noop-set.js +10 -0
  97. package/lib/plugin-override.js +90 -0
  98. package/lib/plugin-utils.js +169 -0
  99. package/lib/promise.js +23 -0
  100. package/lib/reply.js +1030 -0
  101. package/lib/req-id-gen-factory.js +52 -0
  102. package/lib/request.js +391 -0
  103. package/lib/route.js +686 -0
  104. package/lib/schema-controller.js +164 -0
  105. package/lib/schemas.js +207 -0
  106. package/lib/server.js +441 -0
  107. package/lib/symbols.js +71 -0
  108. package/lib/validation.js +280 -0
  109. package/lib/warnings.js +57 -0
  110. package/lib/wrap-thenable.js +84 -0
  111. package/package.json +225 -0
  112. package/scripts/validate-ecosystem-links.js +179 -0
  113. package/test/404s.test.js +2035 -0
  114. package/test/500s.test.js +422 -0
  115. package/test/allow-unsafe-regex.test.js +92 -0
  116. package/test/als.test.js +65 -0
  117. package/test/async-await.test.js +705 -0
  118. package/test/async-dispose.test.js +20 -0
  119. package/test/async_hooks.test.js +52 -0
  120. package/test/body-limit.test.js +224 -0
  121. package/test/buffer.test.js +74 -0
  122. package/test/build/error-serializer.test.js +36 -0
  123. package/test/build/version.test.js +14 -0
  124. package/test/build-certificate.js +109 -0
  125. package/test/bundler/README.md +29 -0
  126. package/test/bundler/esbuild/bundler-test.js +32 -0
  127. package/test/bundler/esbuild/package.json +10 -0
  128. package/test/bundler/esbuild/src/fail-plugin-version.js +14 -0
  129. package/test/bundler/esbuild/src/index.js +9 -0
  130. package/test/bundler/webpack/bundler-test.js +32 -0
  131. package/test/bundler/webpack/package.json +11 -0
  132. package/test/bundler/webpack/src/fail-plugin-version.js +14 -0
  133. package/test/bundler/webpack/src/index.js +9 -0
  134. package/test/bundler/webpack/webpack.config.js +15 -0
  135. package/test/case-insensitive.test.js +102 -0
  136. package/test/chainable.test.js +40 -0
  137. package/test/child-logger-factory.test.js +128 -0
  138. package/test/client-timeout.test.js +38 -0
  139. package/test/close-pipelining.test.js +78 -0
  140. package/test/close.test.js +706 -0
  141. package/test/conditional-pino.test.js +47 -0
  142. package/test/connection-timeout.test.js +42 -0
  143. package/test/constrained-routes.test.js +1138 -0
  144. package/test/content-length.test.js +174 -0
  145. package/test/content-parser.test.js +739 -0
  146. package/test/content-type.test.js +181 -0
  147. package/test/context-config.test.js +164 -0
  148. package/test/custom-http-server.test.js +118 -0
  149. package/test/custom-parser-async.test.js +59 -0
  150. package/test/custom-parser.0.test.js +701 -0
  151. package/test/custom-parser.1.test.js +266 -0
  152. package/test/custom-parser.2.test.js +91 -0
  153. package/test/custom-parser.3.test.js +208 -0
  154. package/test/custom-parser.4.test.js +218 -0
  155. package/test/custom-parser.5.test.js +130 -0
  156. package/test/custom-querystring-parser.test.js +129 -0
  157. package/test/decorator.test.js +1330 -0
  158. package/test/delete.test.js +344 -0
  159. package/test/diagnostics-channel/404.test.js +49 -0
  160. package/test/diagnostics-channel/async-delay-request.test.js +65 -0
  161. package/test/diagnostics-channel/async-request.test.js +64 -0
  162. package/test/diagnostics-channel/error-before-handler.test.js +35 -0
  163. package/test/diagnostics-channel/error-request.test.js +53 -0
  164. package/test/diagnostics-channel/error-status.test.js +123 -0
  165. package/test/diagnostics-channel/init.test.js +50 -0
  166. package/test/diagnostics-channel/sync-delay-request.test.js +49 -0
  167. package/test/diagnostics-channel/sync-request-reply.test.js +51 -0
  168. package/test/diagnostics-channel/sync-request.test.js +54 -0
  169. package/test/encapsulated-child-logger-factory.test.js +69 -0
  170. package/test/encapsulated-error-handler.test.js +237 -0
  171. package/test/esm/errorCodes.test.mjs +10 -0
  172. package/test/esm/esm.test.mjs +13 -0
  173. package/test/esm/index.test.js +8 -0
  174. package/test/esm/named-exports.mjs +14 -0
  175. package/test/esm/other.mjs +8 -0
  176. package/test/esm/plugin.mjs +8 -0
  177. package/test/fastify-instance.test.js +300 -0
  178. package/test/find-route.test.js +152 -0
  179. package/test/fluent-schema.test.js +209 -0
  180. package/test/genReqId.test.js +426 -0
  181. package/test/handler-context.test.js +45 -0
  182. package/test/handler-timeout.test.js +367 -0
  183. package/test/has-route.test.js +88 -0
  184. package/test/header-overflow.test.js +55 -0
  185. package/test/helper.js +496 -0
  186. package/test/hooks-async.test.js +1099 -0
  187. package/test/hooks.on-listen.test.js +1162 -0
  188. package/test/hooks.on-ready.test.js +421 -0
  189. package/test/hooks.test.js +3578 -0
  190. package/test/http-methods/copy.test.js +35 -0
  191. package/test/http-methods/custom-http-methods.test.js +114 -0
  192. package/test/http-methods/get.test.js +412 -0
  193. package/test/http-methods/head.test.js +263 -0
  194. package/test/http-methods/lock.test.js +108 -0
  195. package/test/http-methods/mkcalendar.test.js +143 -0
  196. package/test/http-methods/mkcol.test.js +35 -0
  197. package/test/http-methods/move.test.js +42 -0
  198. package/test/http-methods/propfind.test.js +136 -0
  199. package/test/http-methods/proppatch.test.js +105 -0
  200. package/test/http-methods/report.test.js +142 -0
  201. package/test/http-methods/search.test.js +233 -0
  202. package/test/http-methods/trace.test.js +21 -0
  203. package/test/http-methods/unlock.test.js +38 -0
  204. package/test/http2/closing.test.js +270 -0
  205. package/test/http2/constraint.test.js +109 -0
  206. package/test/http2/head.test.js +34 -0
  207. package/test/http2/plain.test.js +68 -0
  208. package/test/http2/secure-with-fallback.test.js +113 -0
  209. package/test/http2/secure.test.js +67 -0
  210. package/test/http2/unknown-http-method.test.js +34 -0
  211. package/test/https/custom-https-server.test.js +58 -0
  212. package/test/https/https.test.js +136 -0
  213. package/test/imports.test.js +17 -0
  214. package/test/inject.test.js +502 -0
  215. package/test/input-validation.js +335 -0
  216. package/test/internals/all.test.js +38 -0
  217. package/test/internals/content-type-parser.test.js +111 -0
  218. package/test/internals/context.test.js +31 -0
  219. package/test/internals/decorator.test.js +156 -0
  220. package/test/internals/errors.test.js +982 -0
  221. package/test/internals/handle-request.test.js +270 -0
  222. package/test/internals/hook-runner.test.js +449 -0
  223. package/test/internals/hooks.test.js +96 -0
  224. package/test/internals/initial-config.test.js +383 -0
  225. package/test/internals/logger.test.js +163 -0
  226. package/test/internals/plugin.test.js +170 -0
  227. package/test/internals/promise.test.js +63 -0
  228. package/test/internals/reply-serialize.test.js +714 -0
  229. package/test/internals/reply.test.js +1920 -0
  230. package/test/internals/req-id-gen-factory.test.js +133 -0
  231. package/test/internals/request-validate.test.js +1402 -0
  232. package/test/internals/request.test.js +506 -0
  233. package/test/internals/schema-controller-perf.test.js +40 -0
  234. package/test/internals/server.test.js +91 -0
  235. package/test/internals/validation.test.js +352 -0
  236. package/test/issue-4959.test.js +118 -0
  237. package/test/keep-alive-timeout.test.js +42 -0
  238. package/test/listen.1.test.js +154 -0
  239. package/test/listen.2.test.js +113 -0
  240. package/test/listen.3.test.js +83 -0
  241. package/test/listen.4.test.js +168 -0
  242. package/test/listen.5.test.js +122 -0
  243. package/test/logger/instantiation.test.js +341 -0
  244. package/test/logger/logger-test-utils.js +47 -0
  245. package/test/logger/logging.test.js +460 -0
  246. package/test/logger/options.test.js +579 -0
  247. package/test/logger/request.test.js +292 -0
  248. package/test/logger/response.test.js +183 -0
  249. package/test/logger/tap-parallel-not-ok +0 -0
  250. package/test/max-requests-per-socket.test.js +113 -0
  251. package/test/middleware.test.js +37 -0
  252. package/test/noop-set.test.js +19 -0
  253. package/test/nullable-validation.test.js +187 -0
  254. package/test/options.error-handler.test.js +5 -0
  255. package/test/options.test.js +5 -0
  256. package/test/output-validation.test.js +140 -0
  257. package/test/patch.error-handler.test.js +5 -0
  258. package/test/patch.test.js +5 -0
  259. package/test/plugin.1.test.js +230 -0
  260. package/test/plugin.2.test.js +314 -0
  261. package/test/plugin.3.test.js +287 -0
  262. package/test/plugin.4.test.js +504 -0
  263. package/test/plugin.helper.js +8 -0
  264. package/test/plugin.name.display.js +10 -0
  265. package/test/post-empty-body.test.js +38 -0
  266. package/test/pretty-print.test.js +366 -0
  267. package/test/promises.test.js +125 -0
  268. package/test/proto-poisoning.test.js +145 -0
  269. package/test/put.error-handler.test.js +5 -0
  270. package/test/put.test.js +5 -0
  271. package/test/register.test.js +184 -0
  272. package/test/reply-code.test.js +148 -0
  273. package/test/reply-early-hints.test.js +100 -0
  274. package/test/reply-error.test.js +815 -0
  275. package/test/reply-trailers.test.js +445 -0
  276. package/test/reply-web-stream-locked.test.js +37 -0
  277. package/test/request-error.test.js +624 -0
  278. package/test/request-header-host.test.js +339 -0
  279. package/test/request-id.test.js +118 -0
  280. package/test/request-timeout.test.js +53 -0
  281. package/test/route-hooks.test.js +635 -0
  282. package/test/route-prefix.test.js +904 -0
  283. package/test/route-shorthand.test.js +48 -0
  284. package/test/route.1.test.js +259 -0
  285. package/test/route.2.test.js +100 -0
  286. package/test/route.3.test.js +213 -0
  287. package/test/route.4.test.js +127 -0
  288. package/test/route.5.test.js +211 -0
  289. package/test/route.6.test.js +306 -0
  290. package/test/route.7.test.js +406 -0
  291. package/test/route.8.test.js +225 -0
  292. package/test/router-options.test.js +1108 -0
  293. package/test/same-shape.test.js +124 -0
  294. package/test/schema-examples.test.js +661 -0
  295. package/test/schema-feature.test.js +2198 -0
  296. package/test/schema-serialization.test.js +1171 -0
  297. package/test/schema-special-usage.test.js +1348 -0
  298. package/test/schema-validation.test.js +1572 -0
  299. package/test/scripts/validate-ecosystem-links.test.js +339 -0
  300. package/test/serialize-response.test.js +186 -0
  301. package/test/server.test.js +347 -0
  302. package/test/set-error-handler.test.js +69 -0
  303. package/test/skip-reply-send.test.js +317 -0
  304. package/test/stream-serializers.test.js +40 -0
  305. package/test/stream.1.test.js +94 -0
  306. package/test/stream.2.test.js +129 -0
  307. package/test/stream.3.test.js +198 -0
  308. package/test/stream.4.test.js +176 -0
  309. package/test/stream.5.test.js +188 -0
  310. package/test/sync-routes.test.js +32 -0
  311. package/test/throw.test.js +359 -0
  312. package/test/toolkit.js +63 -0
  313. package/test/trust-proxy.test.js +162 -0
  314. package/test/type-provider.test.js +22 -0
  315. package/test/types/content-type-parser.test-d.ts +72 -0
  316. package/test/types/decorate-request-reply.test-d.ts +18 -0
  317. package/test/types/dummy-plugin.ts +9 -0
  318. package/test/types/errors.test-d.ts +90 -0
  319. package/test/types/fastify.test-d.ts +352 -0
  320. package/test/types/hooks.test-d.ts +550 -0
  321. package/test/types/import.ts +2 -0
  322. package/test/types/instance.test-d.ts +588 -0
  323. package/test/types/logger.test-d.ts +277 -0
  324. package/test/types/plugin.test-d.ts +97 -0
  325. package/test/types/register.test-d.ts +237 -0
  326. package/test/types/reply.test-d.ts +254 -0
  327. package/test/types/request.test-d.ts +188 -0
  328. package/test/types/route.test-d.ts +553 -0
  329. package/test/types/schema.test-d.ts +135 -0
  330. package/test/types/serverFactory.test-d.ts +37 -0
  331. package/test/types/type-provider.test-d.ts +1213 -0
  332. package/test/types/using.test-d.ts +17 -0
  333. package/test/upgrade.test.js +52 -0
  334. package/test/url-rewriting.test.js +122 -0
  335. package/test/use-semicolon-delimiter.test.js +168 -0
  336. package/test/validation-error-handling.test.js +900 -0
  337. package/test/versioned-routes.test.js +603 -0
  338. package/test/web-api.test.js +616 -0
  339. package/test/wrap-thenable.test.js +30 -0
  340. package/types/content-type-parser.d.ts +75 -0
  341. package/types/context.d.ts +22 -0
  342. package/types/errors.d.ts +92 -0
  343. package/types/hooks.d.ts +875 -0
  344. package/types/instance.d.ts +609 -0
  345. package/types/logger.d.ts +107 -0
  346. package/types/plugin.d.ts +44 -0
  347. package/types/register.d.ts +42 -0
  348. package/types/reply.d.ts +81 -0
  349. package/types/request.d.ts +95 -0
  350. package/types/route.d.ts +199 -0
  351. package/types/schema.d.ts +61 -0
  352. package/types/server-factory.d.ts +19 -0
  353. package/types/type-provider.d.ts +130 -0
  354. package/types/utils.d.ts +98 -0
@@ -0,0 +1,2389 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## Factory
4
+ <a id="factory"></a>
5
+
6
+ The Fastify module exports a factory function that is used to create new
7
+ <code><b>Fastify server</b></code> instances. This factory function accepts an
8
+ options object which is used to customize the resulting instance. This document
9
+ describes the properties available in that options object.
10
+
11
+ - [Factory](#factory)
12
+ - [`http`](#http)
13
+ - [`http2`](#http2)
14
+ - [`https`](#https)
15
+ - [`connectionTimeout`](#connectiontimeout)
16
+ - [`keepAliveTimeout`](#keepalivetimeout)
17
+ - [`forceCloseConnections`](#forcecloseconnections)
18
+ - [`maxRequestsPerSocket`](#maxrequestspersocket)
19
+ - [`requestTimeout`](#requesttimeout)
20
+ - [`bodyLimit`](#bodylimit)
21
+ - [`onProtoPoisoning`](#onprotopoisoning)
22
+ - [`onConstructorPoisoning`](#onconstructorpoisoning)
23
+ - [`logger`](#logger)
24
+ - [`loggerInstance`](#loggerinstance)
25
+ - [`disableRequestLogging`](#disablerequestlogging)
26
+ - [`serverFactory`](#serverfactory)
27
+ - [`requestIdHeader`](#requestidheader)
28
+ - [`requestIdLogLabel`](#requestidloglabel)
29
+ - [`genReqId`](#genreqid)
30
+ - [`trustProxy`](#trustproxy)
31
+ - [`pluginTimeout`](#plugintimeout)
32
+ - [`exposeHeadRoutes`](#exposeheadroutes)
33
+ - [`return503OnClosing`](#return503onclosing)
34
+ - [`ajv`](#ajv)
35
+ - [`serializerOpts`](#serializeropts)
36
+ - [`http2SessionTimeout`](#http2sessiontimeout)
37
+ - [`frameworkErrors`](#frameworkerrors)
38
+ - [`clientErrorHandler`](#clienterrorhandler)
39
+ - [`rewriteUrl`](#rewriteurl)
40
+ - [`allowErrorHandlerOverride`](#allowerrorhandleroverride)
41
+ - [RouterOptions](#routeroptions)
42
+ - [`allowUnsafeRegex`](#allowunsaferegex)
43
+ - [`buildPrettyMeta`](#buildprettymeta)
44
+ - [`caseSensitive`](#casesensitive)
45
+ - [`constraints`](#constraints)
46
+ - [`defaultRoute`](#defaultroute)
47
+ - [`ignoreDuplicateSlashes`](#ignoreduplicateslashes)
48
+ - [`ignoreTrailingSlash`](#ignoretrailingslash)
49
+ - [`maxParamLength`](#maxparamlength)
50
+ - [`onBadUrl`](#onbadurl)
51
+ - [`querystringParser`](#querystringparser)
52
+ - [`useSemicolonDelimiter`](#usesemicolondelimiter)
53
+ - [Instance](#instance)
54
+ - [Server Methods](#server-methods)
55
+ - [server](#server)
56
+ - [after](#after)
57
+ - [ready](#ready)
58
+ - [listen](#listen)
59
+ - [addresses](#addresses)
60
+ - [routing](#routing)
61
+ - [route](#route)
62
+ - [hasRoute](#hasroute)
63
+ - [findRoute](#findroute)
64
+ - [close](#close)
65
+ - [decorate\*](#decorate)
66
+ - [register](#register)
67
+ - [addHook](#addhook)
68
+ - [prefix](#prefix)
69
+ - [pluginName](#pluginname)
70
+ - [hasPlugin](#hasplugin)
71
+ - [listeningOrigin](#listeningorigin)
72
+ - [log](#log)
73
+ - [version](#version)
74
+ - [inject](#inject)
75
+ - [addHttpMethod](#addHttpMethod)
76
+ - [addSchema](#addschema)
77
+ - [getSchemas](#getschemas)
78
+ - [getSchema](#getschema)
79
+ - [setReplySerializer](#setreplyserializer)
80
+ - [setValidatorCompiler](#setvalidatorcompiler)
81
+ - [setSchemaErrorFormatter](#setschemaerrorformatter)
82
+ - [setSerializerCompiler](#setserializercompiler)
83
+ - [validatorCompiler](#validatorcompiler)
84
+ - [serializerCompiler](#serializercompiler)
85
+ - [schemaErrorFormatter](#schemaerrorformatter)
86
+ - [schemaController](#schemacontroller)
87
+ - [setNotFoundHandler](#setnotfoundhandler)
88
+ - [setErrorHandler](#seterrorhandler)
89
+ - [setChildLoggerFactory](#setchildloggerfactory)
90
+ - [setGenReqId](#setgenreqid)
91
+ - [addConstraintStrategy](#addconstraintstrategy)
92
+ - [hasConstraintStrategy](#hasconstraintstrategy)
93
+ - [printRoutes](#printroutes)
94
+ - [printPlugins](#printplugins)
95
+ - [addContentTypeParser](#addcontenttypeparser)
96
+ - [hasContentTypeParser](#hascontenttypeparser)
97
+ - [removeContentTypeParser](#removecontenttypeparser)
98
+ - [removeAllContentTypeParsers](#removeallcontenttypeparsers)
99
+ - [getDefaultJsonParser](#getdefaultjsonparser)
100
+ - [defaultTextParser](#defaulttextparser)
101
+ - [errorHandler](#errorhandler)
102
+ - [childLoggerFactory](#childloggerfactory)
103
+ - [Symbol.asyncDispose](#symbolasyncdispose)
104
+ - [initialConfig](#initialconfig)
105
+
106
+ ### `http`
107
+ <a id="factory-http"></a>
108
+
109
+ + Default: `null`
110
+
111
+ An object used to configure the server's listening socket. The options
112
+ are the same as the Node.js core [`createServer`
113
+ method](https://nodejs.org/docs/latest-v20.x/api/http.html#httpcreateserveroptions-requestlistener).
114
+
115
+ This option is ignored if options [`http2`](#factory-http2) or
116
+ [`https`](#factory-https) are set.
117
+
118
+ ### `http2`
119
+ <a id="factory-http2"></a>
120
+
121
+ + Default: `false`
122
+
123
+ If `true` Node.js core's
124
+ [HTTP/2](https://nodejs.org/dist/latest-v20.x/docs/api/http2.html) module is
125
+ used for binding the socket.
126
+
127
+ ### `https`
128
+ <a id="factory-https"></a>
129
+
130
+ + Default: `null`
131
+
132
+ An object used to configure the server's listening socket for TLS. The options
133
+ are the same as the Node.js core [`createServer`
134
+ method](https://nodejs.org/dist/latest-v20.x/docs/api/https.html#https_https_createserver_options_requestlistener).
135
+ When this property is `null`, the socket will not be configured for TLS.
136
+
137
+ This option also applies when the [`http2`](#factory-http2) option is set.
138
+
139
+ ### `connectionTimeout`
140
+ <a id="factory-connection-timeout"></a>
141
+
142
+ + Default: `0` (no timeout)
143
+
144
+ Defines the server timeout in milliseconds. See documentation for
145
+ [`server.timeout`
146
+ property](https://nodejs.org/api/http.html#http_server_timeout) to understand
147
+ the effect of this option.
148
+
149
+ When `serverFactory` option is specified this option is ignored.
150
+
151
+ ### `keepAliveTimeout`
152
+ <a id="factory-keep-alive-timeout"></a>
153
+
154
+ + Default: `72000` (72 seconds)
155
+
156
+ Defines the server keep-alive timeout in milliseconds. See documentation for
157
+ [`server.keepAliveTimeout`
158
+ property](https://nodejs.org/api/http.html#http_server_keepalivetimeout) to
159
+ understand the effect of this option. This option only applies when HTTP/1 is in
160
+ use.
161
+
162
+ When `serverFactory` option is specified this option is ignored.
163
+
164
+ ### `forceCloseConnections`
165
+ <a id="forcecloseconnections"></a>
166
+
167
+ + Default: `"idle"` if the HTTP server allows it, `false` otherwise
168
+
169
+ When set to `true`, upon [`close`](#close) the server will iterate the current
170
+ persistent connections and [destroy their
171
+ sockets](https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketdestroyerror).
172
+
173
+ When used with HTTP/2 server, it will also close all active HTTP/2 sessions.
174
+
175
+ > ℹ️ Note:
176
+ > Since Node.js v24 active sessions are closed by default
177
+
178
+
179
+ > ⚠ Warning:
180
+ > Connections are not inspected to determine if requests have
181
+ > been completed.
182
+
183
+ Fastify will prefer the HTTP server's
184
+ [`closeAllConnections`](https://nodejs.org/dist/latest-v18.x/docs/api/http.html#servercloseallconnections)
185
+ method if supported, otherwise, it will use internal connection tracking.
186
+
187
+ When set to `"idle"`, upon [`close`](#close) the server will iterate the current
188
+ persistent connections which are not sending a request or waiting for a response
189
+ and destroy their sockets. The value is only supported if the HTTP server
190
+ supports the
191
+ [`closeIdleConnections`](https://nodejs.org/dist/latest-v18.x/docs/api/http.html#servercloseidleconnections)
192
+ method, otherwise attempting to set it will throw an exception.
193
+
194
+ ### `maxRequestsPerSocket`
195
+ <a id="factory-max-requests-per-socket"></a>
196
+
197
+ + Default: `0` (no limit)
198
+
199
+ Defines the maximum number of requests a socket can handle before closing keep
200
+ alive connection. See [`server.maxRequestsPerSocket`
201
+ property](https://nodejs.org/dist/latest/docs/api/http.html#http_server_maxrequestspersocket)
202
+ to understand the effect of this option. This option only applies when HTTP/1.1
203
+ is in use. Also, when `serverFactory` option is specified, this option is
204
+ ignored.
205
+
206
+ > ℹ️ Note:
207
+ > At the time of writing, only node >= v16.10.0 supports this option.
208
+
209
+ ### `requestTimeout`
210
+ <a id="factory-request-timeout"></a>
211
+
212
+ + Default: `0` (no limit)
213
+
214
+ Defines the maximum number of milliseconds for receiving the entire request from
215
+ the client. See [`server.requestTimeout`
216
+ property](https://nodejs.org/dist/latest/docs/api/http.html#http_server_requesttimeout)
217
+ to understand the effect of this option.
218
+
219
+ When `serverFactory` option is specified, this option is ignored.
220
+ It must be set to a non-zero value (e.g. 120 seconds) to protect against potential
221
+ Denial-of-Service attacks in case the server is deployed without a reverse proxy
222
+ in front.
223
+
224
+ > ℹ️ Note:
225
+ > At the time of writing, only node >= v14.11.0 supports this option
226
+
227
+ ### `handlerTimeout`
228
+ <a id="factory-handler-timeout"></a>
229
+
230
+ + Default: `0` (no timeout)
231
+
232
+ Defines the maximum number of milliseconds allowed for processing a request
233
+ through the entire route lifecycle (from routing through onRequest, parsing,
234
+ validation, handler execution, and serialization). If the response is not sent
235
+ within this time, a `503 Service Unavailable` error is returned and
236
+ `request.signal` is aborted.
237
+
238
+ Unlike `connectionTimeout` and `requestTimeout` (which operate at the socket
239
+ level), `handlerTimeout` is an application-level timeout that works correctly
240
+ with HTTP keep-alive connections. It can be overridden per-route via
241
+ [route options](./Routes.md#routes-options). When set at both levels, the
242
+ route-level value takes precedence. Routes without an explicit `handlerTimeout`
243
+ inherit the server default. Once a server-level timeout is set, individual
244
+ routes cannot opt out of it — they can only override it with a different
245
+ positive integer.
246
+
247
+ The timeout is **cooperative**: when it fires, Fastify sends the 503 error
248
+ response, but the handler's async work continues to run. Use
249
+ [`request.signal`](./Request.md) to detect cancellation and stop ongoing work
250
+ (database queries, HTTP requests, etc.). APIs that accept a `signal` option
251
+ (`fetch()`, database drivers, `stream.pipeline()`) will cancel automatically.
252
+
253
+ The timeout error (`FST_ERR_HANDLER_TIMEOUT`) is sent through the route's
254
+ [error handler](./Routes.md#routes-options), which can be customized per-route
255
+ to change the status code or response body.
256
+
257
+ When `reply.hijack()` is called, the timeout timer is cleared — the handler
258
+ takes full responsibility for the response lifecycle.
259
+
260
+ > ℹ️ Note:
261
+ > `handlerTimeout` does not apply to 404 handlers or custom not-found handlers
262
+ > set via `setNotFoundHandler()`, as they bypass the route handler lifecycle.
263
+
264
+ ```js
265
+ const fastify = require('fastify')({
266
+ handlerTimeout: 10000 // 10s default for all routes
267
+ })
268
+
269
+ // Override per-route
270
+ fastify.get('/slow-report', { handlerTimeout: 120000 }, async (request) => {
271
+ // Use request.signal for cooperative cancellation
272
+ const data = await db.query(longQuery, { signal: request.signal })
273
+ return data
274
+ })
275
+
276
+ // Customize the timeout response
277
+ fastify.get('/custom-timeout', {
278
+ handlerTimeout: 5000,
279
+ errorHandler: (error, request, reply) => {
280
+ if (error.code === 'FST_ERR_HANDLER_TIMEOUT') {
281
+ reply.code(504).send({ error: 'Gateway Timeout' })
282
+ } else {
283
+ reply.send(error)
284
+ }
285
+ }
286
+ }, async (request) => {
287
+ const result = await externalService.call({ signal: request.signal })
288
+ return result
289
+ })
290
+ ```
291
+
292
+ ### `bodyLimit`
293
+ <a id="factory-body-limit"></a>
294
+
295
+ + Default: `1048576` (1MiB)
296
+
297
+ Defines the maximum payload, in bytes, the server is allowed to accept.
298
+ The default body reader sends [`FST_ERR_CTP_BODY_TOO_LARGE`](./Errors.md#fst_err_ctp_body_too_large)
299
+ reply, if the size of the body exceeds this limit.
300
+ If [`preParsing` hook](./Hooks.md#preparsing) is provided, this limit is applied
301
+ to the size of the stream the hook returns (i.e. the size of "decoded" body).
302
+
303
+ ### `onProtoPoisoning`
304
+ <a id="factory-on-proto-poisoning"></a>
305
+
306
+ + Default: `'error'`
307
+
308
+ Defines what action the framework must take when parsing a JSON object with
309
+ `__proto__`. This functionality is provided by
310
+ [secure-json-parse](https://github.com/fastify/secure-json-parse). See
311
+ [Prototype Poisoning](../Guides/Prototype-Poisoning.md) for more details about
312
+ prototype poisoning attacks.
313
+
314
+ Possible values are `'error'`, `'remove'`, or `'ignore'`.
315
+
316
+ ### `onConstructorPoisoning`
317
+ <a id="factory-on-constructor-poisoning"></a>
318
+
319
+ + Default: `'error'`
320
+
321
+ Defines what action the framework must take when parsing a JSON object with
322
+ `constructor`. This functionality is provided by
323
+ [secure-json-parse](https://github.com/fastify/secure-json-parse). See
324
+ [Prototype Poisoning](../Guides/Prototype-Poisoning.md) for more details about
325
+ prototype poisoning attacks.
326
+
327
+ Possible values are `'error'`, `'remove'`, or `'ignore'`.
328
+
329
+ ### `logger`
330
+ <a id="factory-logger"></a>
331
+
332
+ Fastify includes built-in logging via the [Pino](https://getpino.io/) logger.
333
+ This property is used to configure the internal logger instance.
334
+
335
+ The possible values this property may have are:
336
+
337
+ + Default: `false`. The logger is disabled. All logging methods will point to a
338
+ null logger [abstract-logging](https://npm.im/abstract-logging) instance.
339
+
340
+ + `object`: a standard Pino [options
341
+ object](https://github.com/pinojs/pino/blob/c77d8ec5ce/docs/API.md#constructor).
342
+ This will be passed directly to the Pino constructor. If the following
343
+ properties are not present on the object, they will be added accordingly:
344
+ * `level`: the minimum logging level. If not set, it will be set to
345
+ `'info'`.
346
+ * `serializers`: a hash of serialization functions. By default, serializers
347
+ are added for `req` (incoming request objects), `res` (outgoing response
348
+ objects), and `err` (standard `Error` objects). When a log method receives
349
+ an object with any of these properties then the respective serializer will
350
+ be used for that property. For example:
351
+ ```js
352
+ fastify.get('/foo', function (req, res) {
353
+ req.log.info({req}) // log the serialized request object
354
+ res.send('foo')
355
+ })
356
+ ```
357
+ Any user-supplied serializer will override the default serializer of the
358
+ corresponding property.
359
+
360
+ ### `loggerInstance`
361
+ <a id="factory-logger-instance"></a>
362
+
363
+ + Default: `null`
364
+
365
+ A custom logger instance. The logger must be a Pino instance or conform to the
366
+ Pino interface by having the following methods: `info`, `error`, `debug`,
367
+ `fatal`, `warn`, `trace`, `child`. For example:
368
+ ```js
369
+ const pino = require('pino')();
370
+
371
+ const customLogger = {
372
+ info: function (o, ...n) {},
373
+ warn: function (o, ...n) {},
374
+ error: function (o, ...n) {},
375
+ fatal: function (o, ...n) {},
376
+ trace: function (o, ...n) {},
377
+ debug: function (o, ...n) {},
378
+ child: function() {
379
+ const child = Object.create(this);
380
+ child.pino = pino.child(...arguments);
381
+ return child;
382
+ },
383
+ };
384
+
385
+ const fastify = require('fastify')({ loggerInstance: customLogger });
386
+ ```
387
+
388
+ ### `disableRequestLogging`
389
+ <a id="factory-disable-request-logging"></a>
390
+
391
+ + Default: `false`
392
+
393
+ When logging is enabled, Fastify will issue an `info` level log
394
+ message when a request is received and when the response for that request has
395
+ been sent. By setting this option to `true`, these log messages will be
396
+ disabled. This allows for more flexible request start and end logging by
397
+ attaching custom `onRequest` and `onResponse` hooks.
398
+
399
+ This option can also be a function that receives the Fastify request object
400
+ and returns a boolean. This allows for conditional request logging based on the
401
+ request properties (e.g., URL, headers, decorations).
402
+
403
+ ```js
404
+ const fastify = require('fastify')({
405
+ logger: true,
406
+ disableRequestLogging: (request) => {
407
+ // Disable logging for health check endpoints
408
+ return request.url === '/health' || request.url === '/ready'
409
+ }
410
+ })
411
+ ```
412
+
413
+ The other log entries that will be disabled are:
414
+ - an error log written by the default `onResponse` hook on reply callback errors
415
+ - the error and info logs written by the `defaultErrorHandler`
416
+ on error management
417
+ - the info log written by the `fourOhFour` handler when a
418
+ non existent route is requested
419
+
420
+ Other log messages emitted by Fastify will stay enabled,
421
+ like deprecation warnings and messages
422
+ emitted when requests are received while the server is closing.
423
+
424
+ ```js
425
+ // Examples of hooks to replicate the disabled functionality.
426
+ fastify.addHook('onRequest', (req, reply, done) => {
427
+ req.log.info({ url: req.raw.url, id: req.id }, 'received request')
428
+ done()
429
+ })
430
+
431
+ fastify.addHook('onResponse', (req, reply, done) => {
432
+ req.log.info({ url: req.raw.originalUrl, statusCode: reply.raw.statusCode }, 'request completed')
433
+ done()
434
+ })
435
+ ```
436
+
437
+ ### `serverFactory`
438
+ <a id="custom-http-server"></a>
439
+
440
+ You can pass a custom HTTP server to Fastify by using the `serverFactory`
441
+ option.
442
+
443
+ `serverFactory` is a function that takes a `handler` parameter, which takes the
444
+ `request` and `response` objects as parameters, and an options object, which is
445
+ the same you have passed to Fastify.
446
+
447
+ ```js
448
+ const serverFactory = (handler, opts) => {
449
+ const server = http.createServer((req, res) => {
450
+ handler(req, res)
451
+ })
452
+
453
+ return server
454
+ }
455
+
456
+ const fastify = Fastify({ serverFactory })
457
+
458
+ fastify.get('/', (req, reply) => {
459
+ reply.send({ hello: 'world' })
460
+ })
461
+
462
+ fastify.listen({ port: 3000 })
463
+ ```
464
+
465
+ Internally Fastify uses the API of Node core HTTP server, so if you are using a
466
+ custom server you must be sure to have the same API exposed. If not, you can
467
+ enhance the server instance inside the `serverFactory` function before the
468
+ `return` statement.
469
+
470
+
471
+ ### `requestIdHeader`
472
+ <a id="factory-request-id-header"></a>
473
+
474
+ + Default: `'request-id'`
475
+
476
+ The header name used to set the request-id. See [the
477
+ request-id](./Logging.md#logging-request-id) section.
478
+ Setting `requestIdHeader` to `true` will set the `requestIdHeader` to
479
+ `"request-id"`.
480
+ Setting `requestIdHeader` to a non-empty string will use
481
+ the specified string as the `requestIdHeader`.
482
+ By default `requestIdHeader` is set to `false` and will immediately use [genReqId](#genreqid).
483
+ Setting `requestIdHeader` to an empty String (`""`) will set the
484
+ requestIdHeader to `false`.
485
+
486
+ + Default: `false`
487
+
488
+ ```js
489
+ const fastify = require('fastify')({
490
+ requestIdHeader: 'x-custom-id', // -> use 'X-Custom-Id' header if available
491
+ //requestIdHeader: false, // -> always use genReqId
492
+ })
493
+ ```
494
+
495
+ > ⚠ Warning:
496
+ > Enabling this allows any callers to set `reqId` to a
497
+ > value of their choosing.
498
+ > No validation is performed on `requestIdHeader`.
499
+
500
+ ### `requestIdLogLabel`
501
+ <a id="factory-request-id-log-label"></a>
502
+
503
+ + Default: `'reqId'`
504
+
505
+ Defines the label used for the request identifier when logging the request.
506
+
507
+ ### `genReqId`
508
+ <a id="factory-gen-request-id"></a>
509
+
510
+ + Default: `value of 'request-id' header if provided or monotonically increasing
511
+ integers`
512
+
513
+ Function for generating the request-id. It will receive the _raw_ incoming
514
+ request as a parameter. This function is expected to be error-free.
515
+
516
+ Especially in distributed systems, you may want to override the default ID
517
+ generation behavior as shown below. For generating `UUID`s you may want to check
518
+ out [hyperid](https://github.com/mcollina/hyperid).
519
+
520
+ > ℹ️ Note:
521
+ > `genReqId` will be not called if the header set in
522
+ > <code>[requestIdHeader](#requestidheader)</code> is available (defaults to
523
+ > 'request-id').
524
+
525
+ ```js
526
+ let i = 0
527
+ const fastify = require('fastify')({
528
+ genReqId: function (req) { return i++ }
529
+ })
530
+ ```
531
+
532
+ ### `trustProxy`
533
+ <a id="factory-trust-proxy"></a>
534
+
535
+ + Default: `false`
536
+ + `true/false`: Trust all proxies (`true`) or do not trust any proxies
537
+ (`false`).
538
+ + `string`: Trust only given IP/CIDR (e.g. `'127.0.0.1'`). May be a list of
539
+ comma separated values (e.g. `'127.0.0.1,192.168.1.1/24'`).
540
+ + `Array<string>`: Trust only given IP/CIDR list (e.g. `['127.0.0.1']`).
541
+ + `number`: Trust the nth hop from the front-facing proxy server as the client.
542
+ + `Function`: Custom trust function that takes `address` as first argument
543
+ ```js
544
+ function myTrustFn(address, hop) {
545
+ return address === '1.2.3.4' || hop === 1
546
+ }
547
+ ```
548
+
549
+ By enabling the `trustProxy` option, Fastify will know that it is sitting behind
550
+ a proxy and that the `X-Forwarded-*` header fields may be trusted, which
551
+ otherwise may be easily spoofed.
552
+
553
+ ```js
554
+ const fastify = Fastify({ trustProxy: true })
555
+ ```
556
+
557
+ For more examples, refer to the
558
+ [`@fastify/proxy-addr`](https://www.npmjs.com/package/@fastify/proxy-addr) package.
559
+
560
+ You may access the `ip`, `ips`, `host` and `protocol` values on the
561
+ [`request`](./Request.md) object.
562
+
563
+ ```js
564
+ fastify.get('/', (request, reply) => {
565
+ console.log(request.ip)
566
+ console.log(request.ips)
567
+ console.log(request.host)
568
+ console.log(request.protocol)
569
+ })
570
+ ```
571
+
572
+ > ℹ️ Note:
573
+ > If a request contains multiple `x-forwarded-host` or `x-forwarded-proto`
574
+ > headers, it is only the last one that is used to derive `request.hostname`
575
+ > and `request.protocol`.
576
+
577
+ ### `pluginTimeout`
578
+ <a id="plugin-timeout"></a>
579
+
580
+ + Default: `10000`
581
+
582
+ The maximum amount of time in *milliseconds* in which a plugin can load. If not,
583
+ [`ready`](#ready) will complete with an `Error` with code
584
+ `'ERR_AVVIO_PLUGIN_TIMEOUT'`. When set to `0`, disables this check. This
585
+ controls [avvio](https://www.npmjs.com/package/avvio) 's `timeout` parameter.
586
+
587
+ ### `querystringParser`
588
+ <a id="factory-querystring-parser"></a>
589
+
590
+ The default query string parser that Fastify uses is a more performant fork
591
+ of Node.js's core `querystring` module called
592
+ [`fast-querystring`](https://github.com/anonrig/fast-querystring).
593
+
594
+ You can use this option to use a custom parser, such as
595
+ [`qs`](https://www.npmjs.com/package/qs).
596
+
597
+ If you only want the keys (and not the values) to be case insensitive we
598
+ recommend using a custom parser to convert only the keys to lowercase.
599
+
600
+ ```js
601
+ const qs = require('qs')
602
+ const fastify = require('fastify')({
603
+ routerOptions: {
604
+ querystringParser: str => qs.parse(str)
605
+ }
606
+ })
607
+ ```
608
+
609
+ You can also use Fastify's default parser but change some handling behavior,
610
+ like the example below for case insensitive keys and values:
611
+
612
+ ```js
613
+ const querystring = require('fast-querystring')
614
+ const fastify = require('fastify')({
615
+ routerOptions: {
616
+ querystringParser: str => querystring.parse(str.toLowerCase())
617
+ }
618
+ })
619
+ ```
620
+
621
+ ### `exposeHeadRoutes`
622
+ <a id="exposeHeadRoutes"></a>
623
+
624
+ + Default: `true`
625
+
626
+ Automatically creates a sibling `HEAD` route for each `GET` route defined. If
627
+ you want a custom `HEAD` handler without disabling this option, make sure to
628
+ define it before the `GET` route.
629
+
630
+ ### `return503OnClosing`
631
+ <a id="factory-return-503-on-closing"></a>
632
+
633
+ + Default: `true`
634
+
635
+ When `true`, any request arriving after [`close`](#close) has been called will
636
+ receive a `503 Service Unavailable` response with `Connection: close` header
637
+ (HTTP/1.1). This lets load balancers detect that the server is shutting down and
638
+ stop routing traffic to it.
639
+
640
+ When `false`, requests arriving during the closing phase are routed and
641
+ processed normally. They will still receive a `Connection: close` header so that
642
+ clients do not attempt to reuse the connection.
643
+
644
+ ### `ajv`
645
+ <a id="factory-ajv"></a>
646
+
647
+ Configure the Ajv v8 instance used by Fastify without providing a custom one.
648
+ The default configuration is explained in the
649
+ [#schema-validator](./Validation-and-Serialization.md#schema-validator) section.
650
+
651
+ ```js
652
+ const fastify = require('fastify')({
653
+ ajv: {
654
+ customOptions: {
655
+ removeAdditional: 'all' // Refer to [ajv options](https://ajv.js.org/options.html#removeadditional)
656
+ },
657
+ plugins: [
658
+ require('ajv-merge-patch'),
659
+ [require('ajv-keywords'), 'instanceof']
660
+ // Usage: [plugin, pluginOptions] - Plugin with options
661
+ // Usage: plugin - Plugin without options
662
+ ],
663
+ onCreate: (ajv) => {
664
+ // Modify the ajv instance as you need.
665
+ ajv.addFormat('myFormat', (data) => typeof data === 'string')
666
+ }
667
+ }
668
+ })
669
+ ```
670
+
671
+ ### `serializerOpts`
672
+ <a id="serializer-opts"></a>
673
+
674
+ Customize the options of the default
675
+ [`fast-json-stringify`](https://github.com/fastify/fast-json-stringify#options)
676
+ instance that serializes the response's payload:
677
+
678
+ ```js
679
+ const fastify = require('fastify')({
680
+ serializerOpts: {
681
+ rounding: 'ceil'
682
+ }
683
+ })
684
+ ```
685
+
686
+ ### `http2SessionTimeout`
687
+ <a id="http2-session-timeout"></a>
688
+
689
+ + Default: `72000`
690
+
691
+ Set a default
692
+ [timeout](https://nodejs.org/api/http2.html#http2sessionsettimeoutmsecs-callback)
693
+ to every incoming HTTP/2 session in milliseconds. The session will be closed on
694
+ the timeout.
695
+
696
+ This option is needed to offer a graceful "close" experience when using
697
+ HTTP/2. The low default has been chosen to mitigate denial of service attacks.
698
+ When the server is behind a load balancer or can scale automatically this value
699
+ can be increased to fit the use case. Node core defaults this to `0`.
700
+
701
+ ### `frameworkErrors`
702
+ <a id="framework-errors"></a>
703
+
704
+ + Default: `null`
705
+
706
+ Fastify provides default error handlers for the most common use cases. It is
707
+ possible to override one or more of those handlers with custom code using this
708
+ option.
709
+
710
+ > ℹ️ Note:
711
+ > Only `FST_ERR_BAD_URL` and `FST_ERR_ASYNC_CONSTRAINT` are implemented at present.
712
+
713
+ ```js
714
+ const fastify = require('fastify')({
715
+ frameworkErrors: function (error, req, res) {
716
+ if (error instanceof FST_ERR_BAD_URL) {
717
+ res.code(400)
718
+ return res.send("Provided url is not valid")
719
+ } else if(error instanceof FST_ERR_ASYNC_CONSTRAINT) {
720
+ res.code(400)
721
+ return res.send("Provided header is not valid")
722
+ } else {
723
+ res.send(err)
724
+ }
725
+ }
726
+ })
727
+ ```
728
+
729
+ ### `clientErrorHandler`
730
+ <a id="client-error-handler"></a>
731
+
732
+ Set a
733
+ [clientErrorHandler](https://nodejs.org/api/http.html#http_event_clienterror)
734
+ that listens to `error` events emitted by client connections and responds with a
735
+ `400`.
736
+
737
+ It is possible to override the default `clientErrorHandler` using this option.
738
+
739
+ + Default:
740
+ ```js
741
+ function defaultClientErrorHandler (err, socket) {
742
+ if (err.code === 'ECONNRESET') {
743
+ return
744
+ }
745
+
746
+ const body = JSON.stringify({
747
+ error: http.STATUS_CODES['400'],
748
+ message: 'Client Error',
749
+ statusCode: 400
750
+ })
751
+ this.log.trace({ err }, 'client error')
752
+
753
+ if (socket.writable) {
754
+ socket.end([
755
+ 'HTTP/1.1 400 Bad Request',
756
+ `Content-Length: ${body.length}`,
757
+ `Content-Type: application/json\r\n\r\n${body}`
758
+ ].join('\r\n'))
759
+ }
760
+ }
761
+ ```
762
+
763
+ > ℹ️ Note:
764
+ > `clientErrorHandler` operates with raw sockets. The handler is expected to
765
+ > return a properly formed HTTP response that includes a status line, HTTP headers
766
+ > and a message body. Before attempting to write the socket, the handler should
767
+ > check if the socket is still writable as it may have already been destroyed.
768
+
769
+ ```js
770
+ const fastify = require('fastify')({
771
+ clientErrorHandler: function (err, socket) {
772
+ const body = JSON.stringify({
773
+ error: {
774
+ message: 'Client error',
775
+ code: '400'
776
+ }
777
+ })
778
+
779
+ // `this` is bound to fastify instance
780
+ this.log.trace({ err }, 'client error')
781
+
782
+ // the handler is responsible for generating a valid HTTP response
783
+ socket.end([
784
+ 'HTTP/1.1 400 Bad Request',
785
+ `Content-Length: ${body.length}`,
786
+ `Content-Type: application/json\r\n\r\n${body}`
787
+ ].join('\r\n'))
788
+ }
789
+ })
790
+ ```
791
+
792
+ ### `rewriteUrl`
793
+ <a id="rewrite-url"></a>
794
+
795
+ Set a sync callback function that must return a string that allows rewriting
796
+ URLs. This is useful when you are behind a proxy that changes the URL.
797
+ Rewriting a URL will modify the `url` property of the `req` object.
798
+
799
+ Note that `rewriteUrl` is called _before_ routing, it is not encapsulated and it
800
+ is an instance-wide configuration.
801
+
802
+ ```js
803
+ // @param {object} req The raw Node.js HTTP request, not the `FastifyRequest` object.
804
+ // @this Fastify The root Fastify instance (not an encapsulated instance).
805
+ // @returns {string} The path that the request should be mapped to.
806
+ function rewriteUrl (req) {
807
+ if (req.url === '/hi') {
808
+ this.log.debug({ originalUrl: req.url, url: '/hello' }, 'rewrite url');
809
+ return '/hello'
810
+ } else {
811
+ return req.url;
812
+ }
813
+ }
814
+ ```
815
+
816
+ ## RouterOptions
817
+ <a id="routeroptions"></a>
818
+
819
+ Fastify uses [`find-my-way`](https://github.com/delvedor/find-my-way) for its
820
+ HTTP router. The `routerOptions` parameter allows passing
821
+ [`find-my-way` options](https://github.com/delvedor/find-my-way?tab=readme-ov-file#findmywayoptions)
822
+ to customize the HTTP router within Fastify.
823
+
824
+ ### `allowUnsafeRegex`
825
+ <a id="allow-unsafe-regex"></a>
826
+
827
+ + Default `false`
828
+
829
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which is,
830
+ disabled by default, so routes only allow safe regular expressions. To use
831
+ unsafe expressions, set `allowUnsafeRegex` to `true`.
832
+
833
+ ```js
834
+ fastify.get('/user/:id(^([0-9]+){4}$)', (request, reply) => {
835
+ // Throws an error without allowUnsafeRegex = true
836
+ })
837
+ ```
838
+
839
+
840
+ ### `buildPrettyMeta`
841
+ <a id="build-pretty-meta"></a>
842
+
843
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which
844
+ supports, `buildPrettyMeta` where you can assign a `buildPrettyMeta`
845
+ function to sanitize a route's store object to use with the `prettyPrint`
846
+ functions. This function should accept a single object and return an object.
847
+
848
+ ```js
849
+ fastify.get('/user/:username', (request, reply) => {
850
+ routerOptions: {
851
+ buildPrettyMeta: route => {
852
+ const cleanMeta = Object.assign({}, route.store)
853
+
854
+ // remove private properties
855
+ Object.keys(cleanMeta).forEach(k => {
856
+ if (typeof k === 'symbol') delete cleanMeta[k]
857
+ })
858
+
859
+ return cleanMeta // this will show up in the pretty print output!
860
+ })
861
+ }
862
+ })
863
+ ```
864
+
865
+ ### `caseSensitive`
866
+ <a id="case-sensitive"></a>
867
+
868
+ + Default: `true`
869
+
870
+ When `true` routes are registered as case-sensitive. That is, `/foo`
871
+ is not equal to `/Foo`.
872
+ When `false` then routes are case-insensitive.
873
+
874
+ Please note that setting this option to `false` goes against
875
+ [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1).
876
+
877
+ By setting `caseSensitive` to `false`, all paths will be matched as lowercase,
878
+ but the route parameters or wildcards will maintain their original letter
879
+ casing.
880
+ This option does not affect query strings, please refer to
881
+ [`querystringParser`](#querystringparser) to change their handling.
882
+
883
+ ```js
884
+ fastify.get('/user/:username', (request, reply) => {
885
+ // Given the URL: /USER/NodeJS
886
+ console.log(request.params.username) // -> 'NodeJS'
887
+ })
888
+ ```
889
+
890
+ ### `constraints`
891
+ <a id="constraints"></a>
892
+
893
+ Fastify's built-in route constraints are provided by `find-my-way`, which
894
+ allows constraining routes by `version` or `host`. You can add new constraint
895
+ strategies, or override the built-in strategies, by providing a `constraints`
896
+ object with strategies for `find-my-way`. You can find more information on
897
+ constraint strategies in the
898
+ [find-my-way](https://github.com/delvedor/find-my-way) documentation.
899
+
900
+ ```js
901
+ const customVersionStrategy = {
902
+ storage: function () {
903
+ const versions = {}
904
+ return {
905
+ get: (version) => { return versions[version] || null },
906
+ set: (version, store) => { versions[version] = store }
907
+ }
908
+ },
909
+ deriveVersion: (req, ctx) => {
910
+ return req.headers['accept']
911
+ }
912
+ }
913
+
914
+ const fastify = require('fastify')({
915
+ routerOptions: {
916
+ constraints: {
917
+ version: customVersionStrategy
918
+ }
919
+ }
920
+ })
921
+ ```
922
+
923
+ ### `defaultRoute`
924
+ <a id="on-bad-url"></a>
925
+
926
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which supports,
927
+ can pass a default route with the option defaultRoute.
928
+
929
+ ```js
930
+ const fastify = require('fastify')({
931
+ routerOptions: {
932
+ defaultRoute: (req, res) => {
933
+ res.statusCode = 404
934
+ res.end()
935
+ }
936
+ }
937
+ })
938
+ ```
939
+
940
+ > ℹ️ Note:
941
+ > The `req` and `res` objects passed to `defaultRoute` are the raw Node.js
942
+ > `IncomingMessage` and `ServerResponse` instances. They do **not** expose the
943
+ > Fastify-specific methods available on `FastifyRequest`/`FastifyReply` (for
944
+ > example, `res.send`).
945
+
946
+ ### `ignoreDuplicateSlashes`
947
+ <a id="factory-ignore-duplicate-slashes"></a>
948
+
949
+ + Default: `false`
950
+
951
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) to handle
952
+ routing. You can use `ignoreDuplicateSlashes` option to remove duplicate slashes
953
+ from the path. It removes duplicate slashes in the route path and the request
954
+ URL. This option applies to *all* route registrations for the resulting server
955
+ instance.
956
+
957
+ When `ignoreTrailingSlash` and `ignoreDuplicateSlashes` are both set
958
+ to `true` Fastify will remove duplicate slashes, and then trailing slashes,
959
+ meaning `//a//b//c//` will be converted to `/a/b/c`.
960
+
961
+ ```js
962
+ const fastify = require('fastify')({
963
+ routerOptions: {
964
+ ignoreDuplicateSlashes: true
965
+ }
966
+ })
967
+
968
+ // registers "/foo/bar/"
969
+ fastify.get('///foo//bar//', function (req, reply) {
970
+ reply.send('foo')
971
+ })
972
+ ```
973
+
974
+ ### `ignoreTrailingSlash`
975
+ <a id="ignore-slash"></a>
976
+
977
+ + Default: `false`
978
+
979
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) to handle
980
+ routing. By default, Fastify will take into account the trailing slashes.
981
+ Paths like `/foo` and `/foo/` are treated as different paths. If you want to
982
+ change this, set this flag to `true`. That way, both `/foo` and `/foo/` will
983
+ point to the same route. This option applies to *all* route registrations for
984
+ the resulting server instance.
985
+
986
+ ```js
987
+ const fastify = require('fastify')({
988
+ routerOptions: {
989
+ ignoreTrailingSlash: true
990
+ }
991
+ })
992
+
993
+ // registers both "/foo" and "/foo/"
994
+ fastify.get('/foo/', function (req, reply) {
995
+ reply.send('foo')
996
+ })
997
+
998
+ // registers both "/bar" and "/bar/"
999
+ fastify.get('/bar', function (req, reply) {
1000
+ reply.send('bar')
1001
+ })
1002
+ ```
1003
+
1004
+ ### `maxParamLength`
1005
+ <a id="max-param-length"></a>
1006
+
1007
+ + Default: `100`
1008
+
1009
+ You can set a custom length for parameters in parametric (standard, regex, and
1010
+ multi) routes by using `maxParamLength` option; the default value is 100
1011
+ characters. If the maximum length limit is reached, the not found route will
1012
+ be invoked.
1013
+
1014
+ This can be useful especially if you have a regex-based route, protecting you
1015
+ against [ReDoS
1016
+ attacks](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS).
1017
+
1018
+
1019
+ ### `onBadUrl`
1020
+ <a id="on-bad-url"></a>
1021
+
1022
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which supports,
1023
+ the use case of a badly formatted url (eg: /hello/%world), by default find-my-way
1024
+ will invoke the defaultRoute, unless you specify the onBadUrl option.
1025
+
1026
+ ```js
1027
+ const fastify = require('fastify')({
1028
+ routerOptions: {
1029
+ onBadUrl: (path, req, res) => {
1030
+ res.statusCode = 400
1031
+ res.end(`Bad path: ${path}`)
1032
+ }
1033
+ }
1034
+ })
1035
+ ```
1036
+
1037
+ As with `defaultRoute`, `req` and `res` are the raw Node.js request/response
1038
+ objects and do not provide Fastify's decorated helpers.
1039
+
1040
+ ### `querystringParser`
1041
+ <a id="querystringparser"></a>
1042
+
1043
+ The default query string parser that Fastify uses is the Node.js's core
1044
+ `querystring` module.
1045
+
1046
+ You can use this option to use a custom parser, such as
1047
+ [`qs`](https://www.npmjs.com/package/qs).
1048
+
1049
+ If you only want the keys (and not the values) to be case insensitive we
1050
+ recommend using a custom parser to convert only the keys to lowercase.
1051
+
1052
+ ```js
1053
+ const qs = require('qs')
1054
+ const fastify = require('fastify')({
1055
+ routerOptions: {
1056
+ querystringParser: str => qs.parse(str)
1057
+ }
1058
+ })
1059
+ ```
1060
+
1061
+ You can also use Fastify's default parser but change some handling behavior,
1062
+ like the example below for case insensitive keys and values:
1063
+
1064
+ ```js
1065
+ const querystring = require('node:querystring')
1066
+ const fastify = require('fastify')({
1067
+ routerOptions: {
1068
+ querystringParser: str => querystring.parse(str.toLowerCase())
1069
+ }
1070
+ })
1071
+ ```
1072
+
1073
+ ### `useSemicolonDelimiter`
1074
+ <a id="use-semicolon-delimiter"></a>
1075
+
1076
+ + Default `false`
1077
+
1078
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which supports,
1079
+ separating the path and query string with a `;` character (code 59), e.g. `/dev;foo=bar`.
1080
+ This decision originated from [delvedor/find-my-way#76]
1081
+ (https://github.com/delvedor/find-my-way/issues/76). Thus, this option will support
1082
+ backwards compatibility for the need to split on `;`. To enable support for splitting
1083
+ on `;` set `useSemicolonDelimiter` to `true`.
1084
+
1085
+ ```js
1086
+ const fastify = require('fastify')({
1087
+ routerOptions: {
1088
+ useSemicolonDelimiter: true
1089
+ }
1090
+ })
1091
+
1092
+ fastify.get('/dev', async (request, reply) => {
1093
+ // An example request such as `/dev;foo=bar`
1094
+ // Will produce the following query params result `{ foo = 'bar' }`
1095
+ return request.query
1096
+ })
1097
+ ```
1098
+
1099
+ ### `allowErrorHandlerOverride`
1100
+ <a id="allow-error-handler-override"></a>
1101
+
1102
+ * **Default:** `true`
1103
+
1104
+ > ⚠ Warning:
1105
+ > This option will be set to `false` by default
1106
+ > in the next major release.
1107
+
1108
+ When set to `false`, it prevents `setErrorHandler` from being called
1109
+ multiple times within the same scope, ensuring that the previous error
1110
+ handler is not unintentionally overridden.
1111
+
1112
+ #### Example of incorrect usage:
1113
+
1114
+ ```js
1115
+ app.setErrorHandler(function freeSomeResources () {
1116
+ // Never executed, memory leaks
1117
+ })
1118
+
1119
+ app.setErrorHandler(function anotherErrorHandler () {
1120
+ // Overrides the previous handler
1121
+ })
1122
+ ```
1123
+
1124
+ ## Instance
1125
+
1126
+ ### Server Methods
1127
+
1128
+ #### server
1129
+ <a id="server"></a>
1130
+
1131
+ `fastify.server`: The Node core
1132
+ [server](https://nodejs.org/api/http.html#http_class_http_server) object as
1133
+ returned by the [**`Fastify factory function`**](#factory).
1134
+
1135
+ > ⚠ Warning:
1136
+ > If utilized improperly, certain Fastify features could be disrupted.
1137
+ > It is recommended to only use it for attaching listeners.
1138
+
1139
+ #### after
1140
+ <a id="after"></a>
1141
+
1142
+ Invoked when the current plugin and all the plugins that have been registered
1143
+ within it have finished loading. It is always executed before the method
1144
+ `fastify.ready`.
1145
+
1146
+ ```js
1147
+ fastify
1148
+ .register((instance, opts, done) => {
1149
+ console.log('Current plugin')
1150
+ done()
1151
+ })
1152
+ .after(err => {
1153
+ console.log('After current plugin')
1154
+ })
1155
+ .register((instance, opts, done) => {
1156
+ console.log('Next plugin')
1157
+ done()
1158
+ })
1159
+ .ready(err => {
1160
+ console.log('Everything has been loaded')
1161
+ })
1162
+ ```
1163
+
1164
+ In case `after()` is called without a function, it returns a `Promise`:
1165
+
1166
+ ```js
1167
+ fastify.register(async (instance, opts) => {
1168
+ console.log('Current plugin')
1169
+ })
1170
+
1171
+ await fastify.after()
1172
+ console.log('After current plugin')
1173
+
1174
+ fastify.register(async (instance, opts) => {
1175
+ console.log('Next plugin')
1176
+ })
1177
+
1178
+ await fastify.ready()
1179
+
1180
+ console.log('Everything has been loaded')
1181
+ ```
1182
+
1183
+ #### ready
1184
+ <a id="ready"></a>
1185
+
1186
+ Function called when all the plugins have been loaded. It takes an error
1187
+ parameter if something went wrong.
1188
+ ```js
1189
+ fastify.ready(err => {
1190
+ if (err) throw err
1191
+ })
1192
+ ```
1193
+ If it is called without any arguments, it will return a `Promise`:
1194
+
1195
+ ```js
1196
+ fastify.ready().then(() => {
1197
+ console.log('successfully booted!')
1198
+ }, (err) => {
1199
+ console.log('an error happened', err)
1200
+ })
1201
+ ```
1202
+
1203
+ #### listen
1204
+ <a id="listen"></a>
1205
+
1206
+ Starts the server and internally waits for the `.ready()` event. The signature
1207
+ is `.listen([options][, callback])`. Both the `options` object and the
1208
+ `callback` parameters extend the [Node.js
1209
+ core](https://nodejs.org/api/net.html#serverlistenoptions-callback) options
1210
+ object. Thus, all core options are available with the following additional
1211
+ Fastify specific options:
1212
+
1213
+ * listenTextResolver: Set an optional resolver for the text to log after server
1214
+ has been successfully started. It is possible to override the default
1215
+ `Server listening at [address]` log entry using this option.
1216
+
1217
+ ```js
1218
+ server.listen({
1219
+ port: 9080,
1220
+ listenTextResolver: (address) => { return `Prometheus metrics server is listening at ${address}` }
1221
+ })
1222
+ ```
1223
+
1224
+ By default, the server will listen on the address(es) resolved by `localhost`
1225
+ when no specific host is provided. If listening on any available interface is
1226
+ desired, then specifying `0.0.0.0` for the address will listen on all IPv4
1227
+ addresses. The address argument provided above will then return the first such
1228
+ IPv4 address. The following table details the possible values for `host` when
1229
+ targeting `localhost`, and what the result of those values for `host` will be.
1230
+
1231
+ Host | IPv4 | IPv6
1232
+ --------------|------|-------
1233
+ `::` | ✅<sup>*</sup> | ✅
1234
+ `::` + [`ipv6Only`](https://nodejs.org/api/net.html#serverlistenoptions-callback) | 🚫 | ✅
1235
+ `0.0.0.0` | ✅ | 🚫
1236
+ `localhost` | ✅ | ✅
1237
+ `127.0.0.1` | ✅ | 🚫
1238
+ `::1` | 🚫 | ✅
1239
+
1240
+ <sup>*</sup> Using `::` for the address will listen on all IPv6 addresses and,
1241
+ depending on OS, may also listen on [all IPv4
1242
+ addresses](https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback).
1243
+
1244
+ Be careful when deciding to listen on all interfaces; it comes with inherent
1245
+ [security
1246
+ risks](https://web.archive.org/web/20170831174611/https://snyk.io/blog/mongodb-hack-and-secure-defaults/).
1247
+
1248
+ The default is to listen on `port: 0` (which picks the first available open
1249
+ port) and `host: 'localhost'`:
1250
+
1251
+ ```js
1252
+ fastify.listen((err, address) => {
1253
+ if (err) {
1254
+ fastify.log.error(err)
1255
+ process.exit(1)
1256
+ }
1257
+ })
1258
+ ```
1259
+
1260
+ Specifying an address is also supported:
1261
+
1262
+ ```js
1263
+ fastify.listen({ port: 3000, host: '127.0.0.1' }, (err, address) => {
1264
+ if (err) {
1265
+ fastify.log.error(err)
1266
+ process.exit(1)
1267
+ }
1268
+ })
1269
+ ```
1270
+
1271
+ If no callback is provided a Promise is returned:
1272
+
1273
+ ```js
1274
+ fastify.listen({ port: 3000 })
1275
+ .then((address) => console.log(`server listening on ${address}`))
1276
+ .catch(err => {
1277
+ console.log('Error starting server:', err)
1278
+ process.exit(1)
1279
+ })
1280
+ ```
1281
+
1282
+ When deploying to a Docker, and potentially other, containers, it is advisable
1283
+ to listen on `0.0.0.0` because they do not default to exposing mapped ports to
1284
+ `localhost`:
1285
+
1286
+ ```js
1287
+ fastify.listen({ port: 3000, host: '0.0.0.0' }, (err, address) => {
1288
+ if (err) {
1289
+ fastify.log.error(err)
1290
+ process.exit(1)
1291
+ }
1292
+ })
1293
+ ```
1294
+
1295
+ If the `port` is omitted (or is set to zero), a random available port is
1296
+ automatically chosen (available via `fastify.server.address().port`).
1297
+
1298
+ The default options of listen are:
1299
+
1300
+ ```js
1301
+ fastify.listen({
1302
+ port: 0,
1303
+ host: 'localhost',
1304
+ exclusive: false,
1305
+ readableAll: false,
1306
+ writableAll: false,
1307
+ ipv6Only: false
1308
+ }, (err) => {})
1309
+ ```
1310
+
1311
+ #### addresses
1312
+ <a id="addresses"></a>
1313
+
1314
+ This method returns an array of addresses that the server is listening on. If
1315
+ you call it before `listen()` is called or after the `close()` function, it will
1316
+ return an empty array.
1317
+
1318
+ ```js
1319
+ await fastify.listen({ port: 8080 })
1320
+ const addresses = fastify.addresses()
1321
+ // [
1322
+ // { port: 8080, family: 'IPv6', address: '::1' },
1323
+ // { port: 8080, family: 'IPv4', address: '127.0.0.1' }
1324
+ // ]
1325
+ ```
1326
+
1327
+ Note that the array contains the `fastify.server.address()` too.
1328
+
1329
+ #### routing
1330
+ <a id="routing"></a>
1331
+
1332
+ Method to access the `lookup` method of the internal router and match the
1333
+ request to the appropriate handler:
1334
+
1335
+ ```js
1336
+ fastify.routing(req, res)
1337
+ ```
1338
+
1339
+ #### route
1340
+ <a id="route"></a>
1341
+
1342
+ Method to add routes to the server, it also has shorthand functions, check
1343
+ [here](./Routes.md).
1344
+
1345
+ #### hasRoute
1346
+ <a id="hasRoute"></a>
1347
+
1348
+ Method to check if a route is already registered to the internal router. It
1349
+ expects an object as the payload. `url` and `method` are mandatory fields. It
1350
+ is possible to also specify `constraints`. The method returns `true` if the
1351
+ route is registered or `false` if not.
1352
+
1353
+ ```js
1354
+ const routeExists = fastify.hasRoute({
1355
+ url: '/',
1356
+ method: 'GET',
1357
+ constraints: { version: '1.0.0' } // optional
1358
+ })
1359
+
1360
+ if (routeExists === false) {
1361
+ // add route
1362
+ }
1363
+ ```
1364
+
1365
+ #### findRoute
1366
+ <a id="findRoute"></a>
1367
+
1368
+ Method to retrieve a route already registered to the internal router. It
1369
+ expects an object as the payload. `url` and `method` are mandatory fields. It
1370
+ is possible to also specify `constraints`.
1371
+ The method returns a route object or `null` if the route cannot be found.
1372
+
1373
+ ```js
1374
+ const route = fastify.findRoute({
1375
+ url: '/artists/:artistId',
1376
+ method: 'GET',
1377
+ constraints: { version: '1.0.0' } // optional
1378
+ })
1379
+
1380
+ if (route !== null) {
1381
+ // perform some route checks
1382
+ console.log(route.params) // `{artistId: ':artistId'}`
1383
+ }
1384
+ ```
1385
+
1386
+
1387
+ #### close
1388
+ <a id="close"></a>
1389
+
1390
+ `fastify.close(callback)`: call this function to close the server instance and
1391
+ run the [`'onClose'`](./Hooks.md#on-close) hook.
1392
+
1393
+ Calling `close` will also cause the server to respond to every new incoming
1394
+ request with a `503` error and destroy that request. See [`return503OnClosing`
1395
+ flags](#factory-return-503-on-closing) for changing this behavior.
1396
+
1397
+ If it is called without any arguments, it will return a Promise:
1398
+
1399
+ ```js
1400
+ fastify.close().then(() => {
1401
+ console.log('successfully closed!')
1402
+ }, (err) => {
1403
+ console.log('an error happened', err)
1404
+ })
1405
+ ```
1406
+
1407
+ ##### Shutdown lifecycle
1408
+
1409
+ When `fastify.close()` is called, the following steps happen in order:
1410
+
1411
+ 1. The server is flagged as **closing**. New incoming requests receive a
1412
+ `Connection: close` header (HTTP/1.1) and are handled according to
1413
+ [`return503OnClosing`](#factory-return-503-on-closing).
1414
+ 2. [`preClose`](./Hooks.md#pre-close) hooks execute. The server is still
1415
+ processing in-flight requests at this point.
1416
+ 3. **Connection draining** based on the
1417
+ [`forceCloseConnections`](#forcecloseconnections) option:
1418
+ - `"idle"` — idle keep-alive connections are closed; in-flight requests
1419
+ continue.
1420
+ - `true` — all persistent connections are destroyed immediately.
1421
+ - `false` — no forced closure; idle connections remain open until they time
1422
+ out naturally (see [`keepAliveTimeout`](#keepalivetimeout)).
1423
+ 4. The HTTP server **stops accepting** new TCP connections
1424
+ (`server.close()`). Node.js waits for all in-flight requests to complete
1425
+ before invoking the callback.
1426
+ 5. [`onClose`](./Hooks.md#on-close) hooks execute. All in-flight requests have
1427
+ completed and the server is no longer listening.
1428
+ 6. The `close` callback (or the returned Promise) resolves.
1429
+
1430
+ ```
1431
+ fastify.close() called
1432
+
1433
+ ├─▶ closing = true (new requests receive 503)
1434
+
1435
+ ├─▶ preClose hooks
1436
+ │ (in-flight requests still active)
1437
+
1438
+ ├─▶ Connection draining (forceCloseConnections)
1439
+
1440
+ ├─▶ server.close()
1441
+ │ (waits for in-flight requests to complete)
1442
+
1443
+ ├─▶ onClose hooks
1444
+ │ (server stopped, all requests done)
1445
+
1446
+ └─▶ close callback / Promise resolves
1447
+ ```
1448
+
1449
+ > ℹ️ Note:
1450
+ > Upgraded connections (such as WebSocket) are not tracked by the HTTP
1451
+ > server and will prevent `server.close()` from completing. Close them
1452
+ > explicitly in a [`preClose`](./Hooks.md#pre-close) hook.
1453
+
1454
+ #### decorate*
1455
+ <a id="decorate"></a>
1456
+
1457
+ Function useful if you need to decorate the fastify instance, Reply or Request,
1458
+ check [here](./Decorators.md).
1459
+
1460
+ #### register
1461
+ <a id="register"></a>
1462
+
1463
+ Fastify allows the user to extend its functionality with plugins. A plugin can
1464
+ be a set of routes, a server decorator, or whatever, check [here](./Plugins.md).
1465
+
1466
+ #### addHook
1467
+ <a id="addHook"></a>
1468
+
1469
+ Function to add a specific hook in the lifecycle of Fastify, check
1470
+ [here](./Hooks.md).
1471
+
1472
+ #### prefix
1473
+ <a id="prefix"></a>
1474
+
1475
+ The full path that will be prefixed to a route.
1476
+
1477
+ Example:
1478
+
1479
+ ```js
1480
+ fastify.register(function (instance, opts, done) {
1481
+ instance.get('/foo', function (request, reply) {
1482
+ // Will log "prefix: /v1"
1483
+ request.log.info('prefix: %s', instance.prefix)
1484
+ reply.send({ prefix: instance.prefix })
1485
+ })
1486
+
1487
+ instance.register(function (instance, opts, done) {
1488
+ instance.get('/bar', function (request, reply) {
1489
+ // Will log "prefix: /v1/v2"
1490
+ request.log.info('prefix: %s', instance.prefix)
1491
+ reply.send({ prefix: instance.prefix })
1492
+ })
1493
+
1494
+ done()
1495
+ }, { prefix: '/v2' })
1496
+
1497
+ done()
1498
+ }, { prefix: '/v1' })
1499
+ ```
1500
+
1501
+ #### pluginName
1502
+ <a id="pluginName"></a>
1503
+
1504
+ Name of the current plugin. The root plugin is called `'fastify'`. There are
1505
+ different ways to define a name (in order).
1506
+
1507
+ 1. If you use [fastify-plugin](https://github.com/fastify/fastify-plugin) the
1508
+ metadata `name` is used.
1509
+ 2. If the exported plugin has the `Symbol.for('fastify.display-name')` property,
1510
+ then the value of that property is used.
1511
+ Example: `pluginFn[Symbol.for('fastify.display-name')] = "Custom Name"`
1512
+ 3. If you `module.exports` a plugin the filename is used.
1513
+ 4. If you use a regular [function
1514
+ declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#defining_functions)
1515
+ the function name is used.
1516
+
1517
+ *Fallback*: The first two lines of your plugin will represent the plugin name.
1518
+ Newlines are replaced by ` -- `. This will help to identify the root cause when
1519
+ you deal with many plugins.
1520
+
1521
+ > ⚠ Warning:
1522
+ > If you have to deal with nested plugins, the name differs with the usage of
1523
+ > the [fastify-plugin](https://github.com/fastify/fastify-plugin) because
1524
+ > no new scope is created and therefore we have no place to attach contextual
1525
+ > data. In that case, the plugin name will represent the boot order of all
1526
+ > involved plugins in the format of `fastify -> plugin-A -> plugin-B`.
1527
+
1528
+ #### hasPlugin
1529
+ <a id="hasPlugin"></a>
1530
+
1531
+ Method to check if a specific plugin has been registered. Relies on the plugin
1532
+ metadata name. Returns `true` if the plugin is registered. Otherwise, returns
1533
+ `false`.
1534
+
1535
+ ```js
1536
+ const fastify = require('fastify')()
1537
+ fastify.register(require('@fastify/cookie'), {
1538
+ secret: 'my-secret',
1539
+ parseOptions: {}
1540
+ })
1541
+
1542
+ fastify.ready(() => {
1543
+ fastify.hasPlugin('@fastify/cookie') // true
1544
+ })
1545
+ ```
1546
+
1547
+ #### listeningOrigin
1548
+ <a id="listeningOrigin"></a>
1549
+
1550
+ The current origin the server is listening to.
1551
+ For example, a TCP socket based server returns
1552
+ a base address like `http://127.0.0.1:3000`,
1553
+ and a Unix socket server will return the socket
1554
+ path, e.g. `fastify.temp.sock`.
1555
+
1556
+ #### log
1557
+ <a id="log"></a>
1558
+
1559
+ The logger instance, check [here](./Logging.md).
1560
+
1561
+ #### version
1562
+ <a id="version"></a>
1563
+
1564
+ Fastify version of the instance. Used for plugin support. See
1565
+ [Plugins](./Plugins.md#handle-the-scope) for information on how the version is
1566
+ used by plugins.
1567
+
1568
+ #### inject
1569
+ <a id="inject"></a>
1570
+
1571
+ Fake HTTP injection (for testing purposes)
1572
+ [here](../Guides/Testing.md#benefits-of-using-fastifyinject).
1573
+
1574
+ #### addHttpMethod
1575
+ <a id="addHttpMethod"></a>
1576
+
1577
+ Fastify supports the `GET`, `HEAD`, `TRACE`, `DELETE`, `OPTIONS`,
1578
+ `PATCH`, `PUT` and `POST` HTTP methods by default.
1579
+ The `addHttpMethod` method allows to add any non standard HTTP
1580
+ methods to the server that are [supported by Node.js](https://nodejs.org/api/http.html#httpmethods).
1581
+
1582
+ ```js
1583
+ // Add a new HTTP method called 'MKCOL' that supports a request body
1584
+ fastify.addHttpMethod('MKCOL', { hasBody: true, })
1585
+
1586
+ // Add a new HTTP method called 'COPY' that does not support a request body
1587
+ fastify.addHttpMethod('COPY')
1588
+ ```
1589
+
1590
+ After calling `addHttpMethod`, it is possible to use the route shorthand
1591
+ methods to define routes for the new HTTP method:
1592
+
1593
+ ```js
1594
+ fastify.addHttpMethod('MKCOL', { hasBody: true })
1595
+ fastify.mkcol('/', (req, reply) => {
1596
+ // Handle the 'MKCOL' request
1597
+ })
1598
+ ```
1599
+
1600
+ > ⚠ Warning:
1601
+ > `addHttpMethod` overrides existing methods.
1602
+
1603
+ #### addSchema
1604
+ <a id="add-schema"></a>
1605
+
1606
+ `fastify.addSchema(schemaObj)`, adds a JSON schema to the Fastify instance. This
1607
+ allows you to reuse it everywhere in your application just by using the standard
1608
+ `$ref` keyword.
1609
+
1610
+ To learn more, read the [Validation and
1611
+ Serialization](./Validation-and-Serialization.md) documentation.
1612
+
1613
+ #### getSchemas
1614
+ <a id="get-schemas"></a>
1615
+
1616
+ `fastify.getSchemas()`, returns a hash of all schemas added via `.addSchema`.
1617
+ The keys of the hash are the `$id`s of the JSON Schema provided.
1618
+
1619
+ #### getSchema
1620
+ <a id="get-schema"></a>
1621
+
1622
+ `fastify.getSchema(id)`, return the JSON schema added with `.addSchema` and the
1623
+ matching `id`. It returns `undefined` if it is not found.
1624
+
1625
+ #### setReplySerializer
1626
+ <a id="set-reply-serializer"></a>
1627
+
1628
+ Set the reply serializer for all the routes. This will be used as default if a
1629
+ [Reply.serializer(func)](./Reply.md#serializerfunc) has not been set. The
1630
+ handler is fully encapsulated, so different plugins can set different error
1631
+ handlers. Note: the function parameter is called only for status `2xx`. Check
1632
+ out the [`setErrorHandler`](#seterrorhandler) for errors.
1633
+
1634
+ ```js
1635
+ fastify.setReplySerializer(function (payload, statusCode){
1636
+ // serialize the payload with a sync function
1637
+ return `my serialized ${statusCode} content: ${payload}`
1638
+ })
1639
+ ```
1640
+
1641
+ #### setValidatorCompiler
1642
+ <a id="set-validator-compiler"></a>
1643
+
1644
+ Set the schema validator compiler for all routes. See
1645
+ [#schema-validator](./Validation-and-Serialization.md#schema-validator).
1646
+
1647
+ #### setSchemaErrorFormatter
1648
+ <a id="set-schema-error-formatter"></a>
1649
+
1650
+ Set the schema error formatter for all routes. See
1651
+ [#error-handling](./Validation-and-Serialization.md#schemaerrorformatter).
1652
+
1653
+ #### setSerializerCompiler
1654
+ <a id="set-serializer-resolver"></a>
1655
+
1656
+ Set the schema serializer compiler for all routes. See
1657
+ [#schema-serializer](./Validation-and-Serialization.md#schema-serializer).
1658
+
1659
+ > ℹ️ Note:
1660
+ > [`setReplySerializer`](#set-reply-serializer) has priority if set!
1661
+
1662
+ #### validatorCompiler
1663
+ <a id="validator-compiler"></a>
1664
+
1665
+ This property can be used to get the schema validator. If not set, it will be
1666
+ `null` until the server starts, then it will be a function with the signature
1667
+ `function ({ schema, method, url, httpPart })` that returns the input `schema`
1668
+ compiled to a function for validating data. The input `schema` can access all
1669
+ the shared schemas added with [`.addSchema`](#add-schema) function.
1670
+
1671
+ #### serializerCompiler
1672
+ <a id="serializer-compiler"></a>
1673
+
1674
+ This property can be used to get the schema serializer. If not set, it will be
1675
+ `null` until the server starts, then it will be a function with the signature
1676
+ `function ({ schema, method, url, httpPart })` that returns the input `schema`
1677
+ compiled to a function for validating data. The input `schema` can access all
1678
+ the shared schemas added with [`.addSchema`](#add-schema) function.
1679
+
1680
+ #### schemaErrorFormatter
1681
+ <a id="schema-error-formatter"></a>
1682
+
1683
+ This property can be used to set a function to format errors that happen while
1684
+ the `validationCompiler` fails to validate the schema. See
1685
+ [#error-handling](./Validation-and-Serialization.md#schemaerrorformatter).
1686
+
1687
+ #### schemaController
1688
+ <a id="schema-controller"></a>
1689
+
1690
+ This property can be used to fully manage:
1691
+ - `bucket`: where the schemas of your application will be stored
1692
+ - `compilersFactory`: what module must compile the JSON schemas
1693
+
1694
+ It can be useful when your schemas are stored in another data structure that is
1695
+ unknown to Fastify.
1696
+
1697
+ Another use case is to tweak all the schemas processing. Doing so it is possible
1698
+ to use Ajv v8 JTD or Standalone feature. To use such as JTD or the Standalone
1699
+ mode, refers to the [`@fastify/ajv-compiler`
1700
+ documentation](https://github.com/fastify/ajv-compiler#usage).
1701
+
1702
+ ```js
1703
+ const fastify = Fastify({
1704
+ schemaController: {
1705
+ /**
1706
+ * This factory is called whenever `fastify.register()` is called.
1707
+ * It may receive as input the schemas of the parent context if some schemas have been added.
1708
+ * @param {object} parentSchemas these schemas will be returned by the
1709
+ * `getSchemas()` method function of the returned `bucket`.
1710
+ */
1711
+ bucket: function factory (parentSchemas) {
1712
+ return {
1713
+ add (inputSchema) {
1714
+ // This function must store the schema added by the user.
1715
+ // This function is invoked when `fastify.addSchema()` is called.
1716
+ },
1717
+ getSchema (schema$id) {
1718
+ // This function must return the raw schema requested by the `schema$id`.
1719
+ // This function is invoked when `fastify.getSchema(id)` is called.
1720
+ return aSchema
1721
+ },
1722
+ getSchemas () {
1723
+ // This function must return all the schemas referenced by the routes schemas' $ref
1724
+ // It must return a JSON where the property is the schema `$id` and the value is the raw JSON Schema.
1725
+ const allTheSchemaStored = {
1726
+ 'schema$id1': schema1,
1727
+ 'schema$id2': schema2
1728
+ }
1729
+ return allTheSchemaStored
1730
+ }
1731
+ }
1732
+ },
1733
+
1734
+ /**
1735
+ * The compilers factory lets you fully control the validator and serializer
1736
+ * in the Fastify's lifecycle, providing the encapsulation to your compilers.
1737
+ */
1738
+ compilersFactory: {
1739
+ /**
1740
+ * This factory is called whenever a new validator instance is needed.
1741
+ * It may be called whenever `fastify.register()` is called only if new schemas have been added to the
1742
+ * encapsulation context.
1743
+ * It may receive as input the schemas of the parent context if some schemas have been added.
1744
+ * @param {object} externalSchemas these schemas will be returned by the
1745
+ * `bucket.getSchemas()`. Needed to resolve the external references $ref.
1746
+ * @param {object} ajvServerOption the server `ajv` options to build your compilers accordingly
1747
+ */
1748
+ buildValidator: function factory (externalSchemas, ajvServerOption) {
1749
+ // This factory function must return a schema validator compiler.
1750
+ // See [#schema-validator](./Validation-and-Serialization.md#schema-validator) for details.
1751
+ const yourAjvInstance = new Ajv(ajvServerOption.customOptions)
1752
+ return function validatorCompiler ({ schema, method, url, httpPart }) {
1753
+ return yourAjvInstance.compile(schema)
1754
+ }
1755
+ },
1756
+
1757
+ /**
1758
+ * This factory is called whenever a new serializer instance is needed.
1759
+ * It may be called whenever `fastify.register()` is called only if new schemas have been added to the
1760
+ * encapsulation context.
1761
+ * It may receive as input the schemas of the parent context if some schemas have been added.
1762
+ * @param {object} externalSchemas these schemas will be returned by the
1763
+ * `bucket.getSchemas()`. Needed to resolve the external references $ref.
1764
+ * @param {object} serializerOptsServerOption the server `serializerOpts`
1765
+ * options to build your compilers accordingly
1766
+ */
1767
+ buildSerializer: function factory (externalSchemas, serializerOptsServerOption) {
1768
+ // This factory function must return a schema serializer compiler.
1769
+ // See [#schema-serializer](./Validation-and-Serialization.md#schema-serializer) for details.
1770
+ return function serializerCompiler ({ schema, method, url, httpStatus, contentType }) {
1771
+ return data => JSON.stringify(data)
1772
+ }
1773
+ }
1774
+ }
1775
+ }
1776
+ });
1777
+ ```
1778
+
1779
+ #### setNotFoundHandler
1780
+ <a id="set-not-found-handler"></a>
1781
+
1782
+ `fastify.setNotFoundHandler(handler(request, reply))`: set the 404 handler. This
1783
+ call is encapsulated by prefix, so different plugins can set different not found
1784
+ handlers if a different [`prefix` option](./Plugins.md#route-prefixing-option)
1785
+ is passed to `fastify.register()`. The handler is treated as a regular route
1786
+ handler so requests will go through the full [Fastify
1787
+ lifecycle](./Lifecycle.md#lifecycle) for unexisting URLs.
1788
+ *async-await* is supported as well.
1789
+ Badly formatted URLs are sent to the [`onBadUrl`](#onbadurl)
1790
+ handler instead.
1791
+
1792
+ You can also register [`preValidation`](./Hooks.md#route-hooks) and
1793
+ [`preHandler`](./Hooks.md#route-hooks) hooks for the 404 handler.
1794
+
1795
+ > ℹ️ Note:
1796
+ > The `preValidation` hook registered using this method will run for a
1797
+ > route that Fastify does not recognize and **not** when a route handler manually
1798
+ > calls [`reply.callNotFound`](./Reply.md#call-not-found). In which case, only
1799
+ > preHandler will be run.
1800
+
1801
+
1802
+ ```js
1803
+ fastify.setNotFoundHandler({
1804
+ preValidation: (req, reply, done) => {
1805
+ // your code
1806
+ done()
1807
+ },
1808
+ preHandler: (req, reply, done) => {
1809
+ // your code
1810
+ done()
1811
+ }
1812
+ }, function (request, reply) {
1813
+ // Default not found handler with preValidation and preHandler hooks
1814
+ })
1815
+
1816
+ fastify.register(function (instance, options, done) {
1817
+ instance.setNotFoundHandler(function (request, reply) {
1818
+ // Handle not found request without preValidation and preHandler hooks
1819
+ // to URLs that begin with '/v1'
1820
+ })
1821
+ done()
1822
+ }, { prefix: '/v1' })
1823
+ ```
1824
+
1825
+ Fastify calls setNotFoundHandler to add a default 404 handler at startup before
1826
+ plugins are registered. If you would like to augment the behavior of the default
1827
+ 404 handler, for example with plugins, you can call setNotFoundHandler with no
1828
+ arguments `fastify.setNotFoundHandler()` within the context of these registered
1829
+ plugins.
1830
+
1831
+ > ℹ️ Note:
1832
+ > Some config properties from the request object will be
1833
+ > undefined inside the custom not found handler. E.g.:
1834
+ > `request.routeOptions.url`, `routeOptions.method` and `routeOptions.config`.
1835
+ > This method design goal is to allow calling the common not found route.
1836
+ > To return a per-route customized 404 response, you can do it in
1837
+ > the response itself.
1838
+
1839
+ #### setErrorHandler
1840
+ <a id="set-error-handler"></a>
1841
+
1842
+ `fastify.setErrorHandler(handler(error, request, reply))`: Set a function that
1843
+ will be invoked whenever an exception is thrown during the request lifecycle.
1844
+ The handler is bound to the Fastify instance and is fully encapsulated, so
1845
+ different plugins can set different error handlers. *async-await* is
1846
+ supported as well.
1847
+
1848
+ If the error `statusCode` is less than 400, Fastify will automatically
1849
+ set it to 500 before calling the error handler.
1850
+
1851
+ `setErrorHandler` will ***not*** catch:
1852
+ - exceptions thrown in an `onResponse` hook because the response has already been
1853
+ sent to the client. Use the `onSend` hook instead.
1854
+ - not found (404) errors. Use [`setNotFoundHandler`](#set-not-found-handler)
1855
+ instead.
1856
+ - Stream errors thrown during piping into the response socket, as
1857
+ headers/response were already sent to the client.
1858
+ Use custom in-stream data to signal such errors.
1859
+
1860
+ ```js
1861
+ fastify.setErrorHandler(function (error, request, reply) {
1862
+ // Log error
1863
+ this.log.error(error)
1864
+ // Send error response
1865
+ reply.status(409).send({ ok: false })
1866
+ })
1867
+ ```
1868
+
1869
+ Fastify is provided with a default function that is called if no error handler
1870
+ is set. It can be accessed using `fastify.errorHandler` and it logs the error
1871
+ with respect to its `statusCode`.
1872
+
1873
+ ```js
1874
+ const statusCode = error.statusCode
1875
+ if (statusCode >= 500) {
1876
+ log.error(error)
1877
+ } else if (statusCode >= 400) {
1878
+ log.info(error)
1879
+ } else {
1880
+ log.error(error)
1881
+ }
1882
+ ```
1883
+
1884
+ > ⚠ Warning:
1885
+ > Avoid calling setErrorHandler multiple times in the same scope.
1886
+ > See [`allowErrorHandlerOverride`](#allowerrorhandleroverride).
1887
+
1888
+ ##### Custom error handler for stream replies
1889
+ <a id="set-error-handler-stream-replies"></a>
1890
+
1891
+ If `Content-Type` differs between the endpoint and error handler, explicitly
1892
+ define it in both. For example, if the endpoint returns an `application/text`
1893
+ stream and the error handler responds with `application/json`, the error handler
1894
+ must explicitly set `Content-Type`. Otherwise, it will fail serialization with
1895
+ a `500` status code. Alternatively, always respond with serialized data in the
1896
+ error handler by manually calling a serialization method (e.g.,
1897
+ `JSON.stringify`).
1898
+
1899
+ ```js
1900
+ fastify.setErrorHandler((err, req, reply) => {
1901
+ reply
1902
+ .code(400)
1903
+ .type('application/json')
1904
+ .send({ error: err.message })
1905
+ })
1906
+ ```
1907
+
1908
+ ```js
1909
+ fastify.setErrorHandler((err, req, reply) => {
1910
+ reply
1911
+ .code(400)
1912
+ .send(JSON.stringify({ error: err.message }))
1913
+ })
1914
+ ```
1915
+
1916
+ #### setChildLoggerFactory
1917
+ <a id="set-child-logger-factory"></a>
1918
+
1919
+ `fastify.setChildLoggerFactory(factory(logger, bindings, opts, rawReq))`: Set a
1920
+ function that will be called when creating a child logger instance for each request
1921
+ which allows for modifying or adding child logger bindings and logger options, or
1922
+ returning a custom child logger implementation.
1923
+
1924
+ Child logger bindings have a performance advantage over per-log bindings because
1925
+ they are pre-serialized by Pino when the child logger is created.
1926
+
1927
+ The first parameter is the parent logger instance, followed by the default bindings
1928
+ and logger options which should be passed to the child logger, and finally
1929
+ the raw request (not a Fastify request object). The function is bound with `this`
1930
+ being the Fastify instance.
1931
+
1932
+ For example:
1933
+ ```js
1934
+ const fastify = require('fastify')({
1935
+ childLoggerFactory: function (logger, bindings, opts, rawReq) {
1936
+ // Calculate additional bindings from the request if needed
1937
+ bindings.traceContext = rawReq.headers['x-cloud-trace-context']
1938
+ return logger.child(bindings, opts)
1939
+ }
1940
+ })
1941
+ ```
1942
+
1943
+ The handler is bound to the Fastify instance and is fully encapsulated, so
1944
+ different plugins can set different logger factories.
1945
+
1946
+ #### setgenreqid
1947
+ <a id="set-gen-req-id"></a>
1948
+
1949
+ `fastify.setGenReqId(function (rawReq))` Synchronous function for setting the request-id
1950
+ for additional Fastify instances. It will receive the _raw_ incoming request as
1951
+ a parameter. The provided function should not throw an Error in any case.
1952
+
1953
+ Especially in distributed systems, you may want to override the default ID
1954
+ generation behavior to handle custom ways of generating different IDs in
1955
+ order to handle different use cases. Such as observability or webhooks plugins.
1956
+
1957
+ For example:
1958
+ ```js
1959
+ const fastify = require('fastify')({
1960
+ genReqId: (req) => {
1961
+ return 'base'
1962
+ }
1963
+ })
1964
+
1965
+ fastify.register((instance, opts, done) => {
1966
+ instance.setGenReqId((req) => {
1967
+ // custom request ID for `/webhooks`
1968
+ return 'webhooks-id'
1969
+ })
1970
+ done()
1971
+ }, { prefix: '/webhooks' })
1972
+
1973
+ fastify.register((instance, opts, done) => {
1974
+ instance.setGenReqId((req) => {
1975
+ // custom request ID for `/observability`
1976
+ return 'observability-id'
1977
+ })
1978
+ done()
1979
+ }, { prefix: '/observability' })
1980
+ ```
1981
+
1982
+ The handler is bound to the Fastify instance and is fully encapsulated, so
1983
+ different plugins can set a different request ID.
1984
+
1985
+ #### addConstraintStrategy
1986
+ <a id="addConstraintStrategy"></a>
1987
+
1988
+ Function to add a custom constraint strategy. To register a new type of
1989
+ constraint, you must add a new constraint strategy that knows how to match
1990
+ values to handlers, and that knows how to get the constraint value from a
1991
+ request.
1992
+
1993
+ Add a custom constraint strategy using the `fastify.addConstraintStrategy`
1994
+ method:
1995
+
1996
+ ```js
1997
+ const customResponseTypeStrategy = {
1998
+ // strategy name for referencing in the route handler `constraints` options
1999
+ name: 'accept',
2000
+ // storage factory for storing routes in the find-my-way route tree
2001
+ storage: function () {
2002
+ let handlers = {}
2003
+ return {
2004
+ get: (type) => { return handlers[type] || null },
2005
+ set: (type, store) => { handlers[type] = store }
2006
+ }
2007
+ },
2008
+ // function to get the value of the constraint from each incoming request
2009
+ deriveConstraint: (req, ctx) => {
2010
+ return req.headers['accept']
2011
+ },
2012
+ // optional flag marking if handlers without constraints can match requests that have a value for this constraint
2013
+ mustMatchWhenDerived: true
2014
+ }
2015
+
2016
+ const router = Fastify();
2017
+ router.addConstraintStrategy(customResponseTypeStrategy);
2018
+ ```
2019
+
2020
+ #### hasConstraintStrategy
2021
+ <a id="hasConstraintStrategy"></a>
2022
+
2023
+ The `fastify.hasConstraintStrategy(strategyName)` checks if there already exists
2024
+ a custom constraint strategy with the same name.
2025
+
2026
+ #### printRoutes
2027
+ <a id="print-routes"></a>
2028
+
2029
+ `fastify.printRoutes()`: Fastify router builds a tree of routes for each HTTP
2030
+ method. If you call the prettyPrint without specifying an HTTP method, it will
2031
+ merge all the trees into one and print it. The merged tree doesn't represent the
2032
+ internal router structure. **Do not use it for debugging.**
2033
+
2034
+ *Remember to call it inside or after a `ready` call.*
2035
+
2036
+ ```js
2037
+ fastify.get('/test', () => {})
2038
+ fastify.get('/test/hello', () => {})
2039
+ fastify.get('/testing', () => {})
2040
+ fastify.get('/testing/:param', () => {})
2041
+ fastify.put('/update', () => {})
2042
+
2043
+ fastify.ready(() => {
2044
+ console.log(fastify.printRoutes())
2045
+ // └── /
2046
+ // ├── test (GET)
2047
+ // │ ├── /hello (GET)
2048
+ // │ └── ing (GET)
2049
+ // │ └── /
2050
+ // │ └── :param (GET)
2051
+ // └── update (PUT)
2052
+ })
2053
+ ```
2054
+
2055
+ If you want to print the internal router tree, you should specify the `method`
2056
+ param. Printed tree will represent the internal router structure.
2057
+ **You can use it for debugging.**
2058
+
2059
+ ```js
2060
+ console.log(fastify.printRoutes({ method: 'GET' }))
2061
+ // └── /
2062
+ // └── test (GET)
2063
+ // ├── /hello (GET)
2064
+ // └── ing (GET)
2065
+ // └── /
2066
+ // └── :param (GET)
2067
+
2068
+ console.log(fastify.printRoutes({ method: 'PUT' }))
2069
+ // └── /
2070
+ // └── update (PUT)
2071
+ ```
2072
+
2073
+ `fastify.printRoutes({ commonPrefix: false })` will print compressed trees. This
2074
+ may be useful when you have a large number of routes with common prefixes.
2075
+ It doesn't represent the internal router structure. **Do not use it for debugging.**
2076
+
2077
+ ```js
2078
+ console.log(fastify.printRoutes({ commonPrefix: false }))
2079
+ // ├── /test (GET)
2080
+ // │ ├── /hello (GET)
2081
+ // │ └── ing (GET)
2082
+ // │ └── /:param (GET)
2083
+ // └── /update (PUT)
2084
+ ```
2085
+
2086
+ `fastify.printRoutes({ includeMeta: (true | []) })` will display properties from
2087
+ the `route.store` object for each displayed route. This can be an `array` of
2088
+ keys (e.g. `['onRequest', Symbol('key')]`), or `true` to display all properties.
2089
+ A shorthand option, `fastify.printRoutes({ includeHooks: true })` will include
2090
+ all [hooks](./Hooks.md).
2091
+
2092
+ ```js
2093
+ fastify.get('/test', () => {})
2094
+ fastify.get('/test/hello', () => {})
2095
+
2096
+ const onTimeout = () => {}
2097
+
2098
+ fastify.addHook('onRequest', () => {})
2099
+ fastify.addHook('onTimeout', onTimeout)
2100
+
2101
+ console.log(fastify.printRoutes({ includeHooks: true, includeMeta: ['errorHandler'] }))
2102
+ // └── /
2103
+ // └── test (GET)
2104
+ // • (onTimeout) ["onTimeout()"]
2105
+ // • (onRequest) ["anonymous()"]
2106
+ // • (errorHandler) "defaultErrorHandler()"
2107
+ // test (HEAD)
2108
+ // • (onTimeout) ["onTimeout()"]
2109
+ // • (onRequest) ["anonymous()"]
2110
+ // • (onSend) ["headRouteOnSendHandler()"]
2111
+ // • (errorHandler) "defaultErrorHandler()"
2112
+ // └── /hello (GET)
2113
+ // • (onTimeout) ["onTimeout()"]
2114
+ // • (onRequest) ["anonymous()"]
2115
+ // • (errorHandler) "defaultErrorHandler()"
2116
+ // /hello (HEAD)
2117
+ // • (onTimeout) ["onTimeout()"]
2118
+ // • (onRequest) ["anonymous()"]
2119
+ // • (onSend) ["headRouteOnSendHandler()"]
2120
+ // • (errorHandler) "defaultErrorHandler()"
2121
+
2122
+ console.log(fastify.printRoutes({ includeHooks: true }))
2123
+ // └── /
2124
+ // └── test (GET)
2125
+ // • (onTimeout) ["onTimeout()"]
2126
+ // • (onRequest) ["anonymous()"]
2127
+ // test (HEAD)
2128
+ // • (onTimeout) ["onTimeout()"]
2129
+ // • (onRequest) ["anonymous()"]
2130
+ // • (onSend) ["headRouteOnSendHandler()"]
2131
+ // └── /hello (GET)
2132
+ // • (onTimeout) ["onTimeout()"]
2133
+ // • (onRequest) ["anonymous()"]
2134
+ // /hello (HEAD)
2135
+ // • (onTimeout) ["onTimeout()"]
2136
+ // • (onRequest) ["anonymous()"]
2137
+ // • (onSend) ["headRouteOnSendHandler()"]
2138
+ ```
2139
+
2140
+ #### printPlugins
2141
+ <a id="print-plugins"></a>
2142
+
2143
+ `fastify.printPlugins()`: Prints the representation of the internal plugin tree
2144
+ used by the avvio, useful for debugging require order issues.
2145
+
2146
+ *Remember to call it inside or after a `ready` call.*
2147
+
2148
+ ```js
2149
+ fastify.register(async function foo (instance) {
2150
+ instance.register(async function bar () {})
2151
+ })
2152
+ fastify.register(async function baz () {})
2153
+
2154
+ fastify.ready(() => {
2155
+ console.error(fastify.printPlugins())
2156
+ // will output the following to stderr:
2157
+ // └── root
2158
+ // ├── foo
2159
+ // │ └── bar
2160
+ // └── baz
2161
+ })
2162
+ ```
2163
+
2164
+ #### addContentTypeParser
2165
+ <a id="addContentTypeParser"></a>
2166
+
2167
+ `fastify.addContentTypeParser(content-type, options, parser)` is used to pass
2168
+ a custom parser for a given content type. Useful for adding parsers for custom
2169
+ content types, e.g. `text/json, application/vnd.oasis.opendocument.text`.
2170
+ `content-type` can be a string, string array or RegExp.
2171
+
2172
+ ```js
2173
+ // The two arguments passed to getDefaultJsonParser are for ProtoType poisoning
2174
+ // and Constructor Poisoning configuration respectively. The possible values are
2175
+ // 'ignore', 'remove', 'error'. ignore skips all validations and it is similar
2176
+ // to calling JSON.parse() directly. See the
2177
+ // [`secure-json-parse` documentation](https://github.com/fastify/secure-json-parse#api) for more information.
2178
+
2179
+ fastify.addContentTypeParser('text/json', { asString: true }, fastify.getDefaultJsonParser('ignore', 'ignore'))
2180
+ ```
2181
+
2182
+ #### hasContentTypeParser
2183
+ <a id="hasContentTypeParser"></a>
2184
+
2185
+ `fastify.hasContentTypeParser(contentType)` is used to check whether there is a
2186
+ content type parser in the current context for the specified content type.
2187
+
2188
+ ```js
2189
+ fastify.hasContentTypeParser('text/json')
2190
+
2191
+ fastify.hasContentTypeParser(/^.+\/json$/)
2192
+ ```
2193
+
2194
+ #### removeContentTypeParser
2195
+ <a id="removeContentTypeParser"></a>
2196
+
2197
+ `fastify.removeContentTypeParser(contentType)` is used to remove content type
2198
+ parsers in the current context. This method allows for example to remove the
2199
+ both built-in parsers for `application/json` and `text/plain`.
2200
+
2201
+ ```js
2202
+ fastify.removeContentTypeParser('application/json')
2203
+
2204
+ fastify.removeContentTypeParser(['application/json', 'text/plain'])
2205
+ ```
2206
+
2207
+ #### removeAllContentTypeParsers
2208
+ <a id="removeAllContentTypeParsers"></a>
2209
+
2210
+ The `fastify.removeAllContentTypeParsers()` method allows all content type
2211
+ parsers in the current context to be removed. A use case of this method is the
2212
+ implementation of catch-all content type parser. Before adding this parser with
2213
+ `fastify.addContentTypeParser()` one could call the
2214
+ `removeAllContentTypeParsers` method.
2215
+
2216
+ For more details about the usage of the different content type parser APIs see
2217
+ [here](./ContentTypeParser.md#usage).
2218
+
2219
+ #### getDefaultJsonParser
2220
+ <a id="getDefaultJsonParser"></a>
2221
+
2222
+ `fastify.getDefaultJsonParser(onProtoPoisoning, onConstructorPoisoning)` takes
2223
+ two arguments. First argument is ProtoType poisoning configuration and second
2224
+ argument is constructor poisoning configuration. See the [`secure-json-parse`
2225
+ documentation](https://github.com/fastify/secure-json-parse#api) for more
2226
+ information.
2227
+
2228
+
2229
+ #### defaultTextParser
2230
+ <a id="defaultTextParser"></a>
2231
+
2232
+ `fastify.defaultTextParser()` can be used to parse content as plain text.
2233
+
2234
+ ```js
2235
+ fastify.addContentTypeParser('text/json', { asString: true }, fastify.defaultTextParser)
2236
+ ```
2237
+
2238
+ #### errorHandler
2239
+ <a id="errorHandler"></a>
2240
+
2241
+ `fastify.errorHandler` can be used to handle errors using fastify's default
2242
+ error handler.
2243
+
2244
+ ```js
2245
+ fastify.get('/', {
2246
+ errorHandler: (error, request, reply) => {
2247
+ if (error.code === 'SOMETHING_SPECIFIC') {
2248
+ reply.send({ custom: 'response' })
2249
+ return
2250
+ }
2251
+
2252
+ fastify.errorHandler(error, request, response)
2253
+ }
2254
+ }, handler)
2255
+ ```
2256
+
2257
+ #### childLoggerFactory
2258
+ <a id="childLoggerFactory"></a>
2259
+
2260
+ `fastify.childLoggerFactory` returns the custom logger factory function for the
2261
+ Fastify instance. See the [`childLoggerFactory` config option](#setchildloggerfactory)
2262
+ for more info.
2263
+
2264
+ #### Symbol.asyncDispose
2265
+ <a id="symbolAsyncDispose"></a>
2266
+
2267
+ `fastify[Symbol.asyncDispose]` is a symbol that can be used to define an
2268
+ asynchronous function that will be called when the Fastify instance is closed.
2269
+
2270
+ It's commonly used alongside the `using` TypeScript keyword to ensure that
2271
+ resources are cleaned up when the Fastify instance is closed.
2272
+
2273
+ This combines perfectly inside short lived processes or unit tests, where you must
2274
+ close all Fastify resources after returning from inside the function.
2275
+
2276
+ ```ts
2277
+ test('Uses app and closes it afterwards', async () => {
2278
+ await using app = fastify();
2279
+ // do something with app.
2280
+ })
2281
+ ```
2282
+
2283
+ In the above example, Fastify is closed automatically after the test finishes.
2284
+
2285
+ Read more about the
2286
+ [ECMAScript Explicit Resource Management](https://tc39.es/proposal-explicit-resource-management)
2287
+ and the [using keyword](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/)
2288
+ introduced in TypeScript 5.2.
2289
+
2290
+ #### initialConfig
2291
+ <a id="initial-config"></a>
2292
+
2293
+ `fastify.initialConfig`: Exposes a frozen read-only object registering the
2294
+ initial options passed down by the user to the Fastify instance.
2295
+
2296
+ The properties that can currently be exposed are:
2297
+ - connectionTimeout
2298
+ - keepAliveTimeout
2299
+ - handlerTimeout
2300
+ - bodyLimit
2301
+ - caseSensitive
2302
+ - http2
2303
+ - https (it will return `false`/`true` or `{ allowHTTP1: true/false }` if
2304
+ explicitly passed)
2305
+ - disableRequestLogging
2306
+ - onProtoPoisoning
2307
+ - onConstructorPoisoning
2308
+ - pluginTimeout
2309
+ - requestIdHeader
2310
+ - requestIdLogLabel
2311
+ - http2SessionTimeout
2312
+ - routerOptions
2313
+ - allowUnsafeRegex
2314
+ - buildPrettyMeta
2315
+ - caseSensitive
2316
+ - constraints
2317
+ - defaultRoute
2318
+ - ignoreDuplicateSlashes
2319
+ - ignoreTrailingSlash
2320
+ - maxParamLength
2321
+ - onBadUrl
2322
+ - querystringParser
2323
+ - useSemicolonDelimiter
2324
+
2325
+ ```js
2326
+ const { readFileSync } = require('node:fs')
2327
+ const Fastify = require('fastify')
2328
+
2329
+ const fastify = Fastify({
2330
+ https: {
2331
+ allowHTTP1: true,
2332
+ key: readFileSync('./fastify.key'),
2333
+ cert: readFileSync('./fastify.cert')
2334
+ },
2335
+ logger: { level: 'trace'},
2336
+ routerOptions: {
2337
+ ignoreTrailingSlash: true,
2338
+ maxParamLength: 200,
2339
+ caseSensitive: true,
2340
+ },
2341
+ trustProxy: '127.0.0.1,192.168.1.1/24',
2342
+ })
2343
+
2344
+ console.log(fastify.initialConfig)
2345
+ /*
2346
+ will log :
2347
+ {
2348
+ https: { allowHTTP1: true },
2349
+ routerOptions: {
2350
+ caseSensitive: true,
2351
+ ignoreTrailingSlash: true,
2352
+ maxParamLength: 200
2353
+ }
2354
+ }
2355
+ */
2356
+
2357
+ fastify.register(async (instance, opts) => {
2358
+ instance.get('/', async (request, reply) => {
2359
+ return instance.initialConfig
2360
+ /*
2361
+ will return :
2362
+ {
2363
+ https: { allowHTTP1: true },
2364
+ routerOptions: {
2365
+ caseSensitive: true,
2366
+ ignoreTrailingSlash: true,
2367
+ maxParamLength: 200
2368
+ }
2369
+ }
2370
+ */
2371
+ })
2372
+
2373
+ instance.get('/error', async (request, reply) => {
2374
+ // will throw an error because initialConfig is read-only
2375
+ // and can not be modified
2376
+ instance.initialConfig.https.allowHTTP1 = false
2377
+
2378
+ return instance.initialConfig
2379
+ })
2380
+ })
2381
+
2382
+ // Start listening.
2383
+ fastify.listen({ port: 3000 }, (err) => {
2384
+ if (err) {
2385
+ fastify.log.error(err)
2386
+ process.exit(1)
2387
+ }
2388
+ })
2389
+ ```