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,1729 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## TypeScript
4
+
5
+ The Fastify framework is written in vanilla JavaScript, and as such type
6
+ definitions are not as easy to maintain; however, since version 2 and beyond,
7
+ maintainers and contributors have put in a great effort to improve the types.
8
+
9
+ The type system was changed in Fastify version 3. The new type system introduces
10
+ generic constraining and defaulting, plus a new way to define schema types such
11
+ as a request body, querystring, and more! As the team works on improving
12
+ framework and type definition synergy, sometimes parts of the API will not be
13
+ typed or may be typed incorrectly. We encourage you to **contribute** to help us
14
+ fill in the gaps. Just make sure to read our
15
+ [`CONTRIBUTING.md`](https://github.com/fastify/fastify/blob/main/CONTRIBUTING.md)
16
+ file before getting started to make sure things go smoothly!
17
+
18
+ > The documentation in this section covers Fastify version 3.x typings
19
+
20
+ > Plugins may or may not include typings. See [Plugins](#plugins) for more
21
+ > information. We encourage users to send pull requests to improve typings
22
+ > support.
23
+
24
+ 🚨 Don't forget to install `@types/node`
25
+
26
+ ## Learn By Example
27
+
28
+ The best way to learn the Fastify type system is by example! The following four
29
+ examples should cover the most common Fastify development cases. After the
30
+ examples there is further, more detailed documentation for the type system.
31
+
32
+ ### Getting Started
33
+
34
+ This example will get you up and running with Fastify and TypeScript. It results
35
+ in a blank http Fastify server.
36
+
37
+ 1. Create a new npm project, install Fastify, and install typescript & Node.js
38
+ types as peer dependencies:
39
+ ```bash
40
+ npm init -y
41
+ npm i fastify
42
+ npm i -D typescript @types/node
43
+ ```
44
+ 2. Add the following lines to the `"scripts"` section of the `package.json`:
45
+ ```json
46
+ {
47
+ "scripts": {
48
+ "build": "tsc -p tsconfig.json",
49
+ "start": "node index.js"
50
+ }
51
+ }
52
+ ```
53
+
54
+ 3. Initialize a TypeScript configuration file:
55
+ ```bash
56
+ npx tsc --init
57
+ ```
58
+ or use one of the [recommended
59
+ ones](https://github.com/tsconfig/bases#node-14-tsconfigjson).
60
+
61
+ > ℹ️ Note:
62
+ > Set `target` property in `tsconfig.json` to `es2017` or greater to avoid
63
+ > [FastifyDeprecation](https://github.com/fastify/fastify/issues/3284) warning.
64
+
65
+ 4. Create an `index.ts` file - this will contain the server code
66
+ 5. Add the following code block to your file:
67
+ ```typescript
68
+ import fastify from 'fastify'
69
+
70
+ const server = fastify()
71
+
72
+ server.get('/ping', async (request, reply) => {
73
+ return 'pong\n'
74
+ })
75
+
76
+ server.listen({ port: 8080 }, (err, address) => {
77
+ if (err) {
78
+ console.error(err)
79
+ process.exit(1)
80
+ }
81
+ console.log(`Server listening at ${address}`)
82
+ })
83
+ ```
84
+ 6. Run `npm run build` - this will compile `index.ts` into `index.js` which can
85
+ be executed using Node.js. If you run into any errors please open an issue in
86
+ [fastify/help](https://github.com/fastify/help/)
87
+ 7. Run `npm run start` to run the Fastify server
88
+ 8. You should see `Server listening at http://127.0.0.1:8080` in your console
89
+ 9. Try out your server using `curl localhost:8080/ping`, it should return `pong`
90
+ 🏓
91
+
92
+ 🎉 You now have a working Typescript Fastify server! This example demonstrates
93
+ the simplicity of the version 3.x type system. By default, the type system
94
+ assumes you are using an `http` server. The later examples will demonstrate how
95
+ to create more complex servers such as `https` and `http2`, how to specify route
96
+ schemas, and more!
97
+
98
+ > For more examples on initializing Fastify with TypeScript (such as enabling
99
+ > HTTP2) check out the detailed API section [here][Fastify]
100
+
101
+ ### Using Generics
102
+
103
+ The type system heavily relies on generic properties to provide the most
104
+ accurate development experience. While some may find the overhead a bit
105
+ cumbersome, the tradeoff is worth it! This example will dive into implementing
106
+ generic types for route schemas and the dynamic properties located on the
107
+ route-level `request` object.
108
+
109
+ 1. If you did not complete the previous example, follow steps 1-4 to get set up.
110
+ 2. Inside `index.ts`, define three interfaces `IQuerystring`,`IHeaders` and `IReply`:
111
+ ```typescript
112
+ interface IQuerystring {
113
+ username: string;
114
+ password: string;
115
+ }
116
+
117
+ interface IHeaders {
118
+ 'h-Custom': string;
119
+ }
120
+
121
+ interface IReply {
122
+ 200: { success: boolean };
123
+ 302: { url: string };
124
+ '4xx': { error: string };
125
+ }
126
+ ```
127
+ 3. Using the three interfaces, define a new API route and pass them as generics.
128
+ The shorthand route methods (i.e. `.get`) accept a generic object
129
+ `RouteGenericInterface` containing five named properties: `Body`,
130
+ `Querystring`, `Params`, `Headers` and `Reply`. The interfaces `Body`,
131
+ `Querystring`, `Params` and `Headers` will be passed down through the route
132
+ method into the route method handler `request` instance and the `Reply`
133
+ interface to the `reply` instance.
134
+ ```typescript
135
+ server.get<{
136
+ Querystring: IQuerystring,
137
+ Headers: IHeaders,
138
+ Reply: IReply
139
+ }>('/auth', async (request, reply) => {
140
+ const { username, password } = request.query
141
+ const customerHeader = request.headers['h-Custom']
142
+ // do something with request data
143
+
144
+ // chaining .statusCode/.code calls with .send allows type narrowing. For example:
145
+ // this works
146
+ reply.code(200).send({ success: true });
147
+ // but this gives a type error
148
+ reply.code(200).send('uh-oh');
149
+ // it even works for wildcards
150
+ reply.code(404).send({ error: 'Not found' });
151
+ return { success: true }
152
+ })
153
+ ```
154
+
155
+ 4. Build and run the server code with `npm run build` and `npm run start`
156
+ 5. Query the API
157
+ ```bash
158
+ curl localhost:8080/auth?username=admin&password=Password123!
159
+ ```
160
+ And it should return back `logged in!`
161
+ 6. But wait there's more! The generic interfaces are also available inside route
162
+ level hook methods. Modify the previous route by adding a `preValidation`
163
+ hook:
164
+ ```typescript
165
+ server.get<{
166
+ Querystring: IQuerystring,
167
+ Headers: IHeaders,
168
+ Reply: IReply
169
+ }>('/auth', {
170
+ preValidation: (request, reply, done) => {
171
+ const { username, password } = request.query
172
+ done(username !== 'admin' ? new Error('Must be admin') : undefined) // only validate `admin` account
173
+ }
174
+ }, async (request, reply) => {
175
+ const customerHeader = request.headers['h-Custom']
176
+ // do something with request data
177
+ return { success: true }
178
+ })
179
+ ```
180
+ 7. Build and run and query with the `username` query string option set to
181
+ anything other than `admin`. The API should now return a HTTP 500 error
182
+ `{"statusCode":500,"error":"Internal Server Error","message":"Must be
183
+ admin"}`
184
+
185
+ 🎉 Good work, now you can define interfaces for each route and have strictly
186
+ typed request and reply instances. Other parts of the Fastify type system rely
187
+ on generic properties. Make sure to reference the detailed type system
188
+ documentation below to learn more about what is available.
189
+
190
+ ### JSON Schema
191
+
192
+ To validate your requests and responses you can use JSON Schema files. If you
193
+ didn't know already, defining schemas for your Fastify routes can increase their
194
+ throughput! Check out the [Validation and
195
+ Serialization](./Validation-and-Serialization.md) documentation for more info.
196
+
197
+ Also it has the advantage to use the defined type within your handlers
198
+ (including pre-validation, etc.).
199
+
200
+ Here are some options on how to achieve this.
201
+
202
+ #### Fastify Type Providers
203
+
204
+ Fastify offers two packages wrapping `json-schema-to-ts` and `typebox`:
205
+
206
+ - [`@fastify/type-provider-json-schema-to-ts`](https://github.com/fastify/fastify-type-provider-json-schema-to-ts)
207
+ - [`@fastify/type-provider-typebox`](https://github.com/fastify/fastify-type-provider-typebox)
208
+
209
+ And a `zod` wrapper by a third party called [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod)
210
+
211
+ They simplify schema validation setup and you can read more about them in [Type
212
+ Providers](./Type-Providers.md) page.
213
+
214
+ Below is how to setup schema validation using the `typebox`,
215
+ `json-schema-to-typescript`, and `json-schema-to-ts` packages without type
216
+ providers.
217
+
218
+ #### TypeBox
219
+
220
+ A useful library for building types and a schema at once is [TypeBox](https://www.npmjs.com/package/typebox).
221
+ With TypeBox you define your schema within your code and use them directly as
222
+ types or schemas as you need them.
223
+
224
+ When you want to use it for validation of some payload in a fastify route you
225
+ can do it as follows:
226
+
227
+ 1. Install `typebox` in your project.
228
+
229
+ ```bash
230
+ npm i typebox
231
+ ```
232
+
233
+ 2. Define the schema you need with `Type` and create the respective type with
234
+ `Static`.
235
+
236
+ ```typescript
237
+ import { Static, Type } from 'typebox'
238
+
239
+ export const User = Type.Object({
240
+ name: Type.String(),
241
+ mail: Type.Optional(Type.String({ format: 'email' })),
242
+ })
243
+
244
+ export type UserType = Static<typeof User>
245
+ ```
246
+
247
+ 3. Use the defined type and schema during the definition of your route
248
+
249
+ ```typescript
250
+ import Fastify from 'fastify'
251
+ // ...
252
+
253
+ const fastify = Fastify()
254
+
255
+ fastify.post<{ Body: UserType, Reply: UserType }>(
256
+ '/',
257
+ {
258
+ schema: {
259
+ body: User,
260
+ response: {
261
+ 200: User
262
+ },
263
+ },
264
+ },
265
+ (request, reply) => {
266
+ // The `name` and `mail` types are automatically inferred
267
+ const { name, mail } = request.body;
268
+ reply.status(200).send({ name, mail });
269
+ }
270
+ )
271
+ ```
272
+
273
+ #### json-schema-to-typescript
274
+
275
+ In the last example we used Typebox to define the types and schemas for our
276
+ route. Many users will already be using JSON Schemas to define these properties,
277
+ and luckily there is a way to transform existing JSON Schemas into TypeScript
278
+ interfaces!
279
+
280
+ 1. If you did not complete the 'Getting Started' example, go back and follow
281
+ steps 1-4 first.
282
+ 2. Install the `json-schema-to-typescript` module:
283
+
284
+ ```bash
285
+ npm i -D json-schema-to-typescript
286
+ ```
287
+
288
+ 3. Create a new folder called `schemas` and add two files `headers.json` and
289
+ `querystring.json`. Copy and paste the following schema definitions into the
290
+ respective files:
291
+
292
+ ```json
293
+ {
294
+ "title": "Headers Schema",
295
+ "type": "object",
296
+ "properties": {
297
+ "h-Custom": { "type": "string" }
298
+ },
299
+ "additionalProperties": false,
300
+ "required": ["h-Custom"]
301
+ }
302
+ ```
303
+
304
+ ```json
305
+ {
306
+ "title": "Querystring Schema",
307
+ "type": "object",
308
+ "properties": {
309
+ "username": { "type": "string" },
310
+ "password": { "type": "string" }
311
+ },
312
+ "additionalProperties": false,
313
+ "required": ["username", "password"]
314
+ }
315
+ ```
316
+
317
+ 4. Add a `compile-schemas` script to the package.json:
318
+
319
+ ```json
320
+ {
321
+ "scripts": {
322
+ "compile-schemas": "json2ts -i schemas -o types"
323
+ }
324
+ }
325
+ ```
326
+
327
+ `json2ts` is a CLI utility included in `json-schema-to-typescript`. `schemas`
328
+ is the input path, and `types` is the output path.
329
+ 5. Run `npm run compile-schemas`. Two new files should have been created in the
330
+ `types` directory.
331
+ 6. Update `index.ts` to have the following code:
332
+
333
+ ```typescript
334
+ import fastify from 'fastify'
335
+
336
+ // import json schemas as normal
337
+ import QuerystringSchema from './schemas/querystring.json'
338
+ import HeadersSchema from './schemas/headers.json'
339
+
340
+ // import the generated interfaces
341
+ import { QuerystringSchema as QuerystringSchemaInterface } from './types/querystring'
342
+ import { HeadersSchema as HeadersSchemaInterface } from './types/headers'
343
+
344
+ const server = fastify()
345
+
346
+ server.get<{
347
+ Querystring: QuerystringSchemaInterface,
348
+ Headers: HeadersSchemaInterface
349
+ }>('/auth', {
350
+ schema: {
351
+ querystring: QuerystringSchema,
352
+ headers: HeadersSchema
353
+ },
354
+ preValidation: (request, reply, done) => {
355
+ const { username, password } = request.query
356
+ done(username !== 'admin' ? new Error('Must be admin') : undefined)
357
+ }
358
+ // or if using async
359
+ // preValidation: async (request, reply) => {
360
+ // const { username, password } = request.query
361
+ // if (username !== "admin") throw new Error("Must be admin");
362
+ // }
363
+ }, async (request, reply) => {
364
+ const customerHeader = request.headers['h-Custom']
365
+ // do something with request data
366
+ return `logged in!`
367
+ })
368
+
369
+ server.route<{
370
+ Querystring: QuerystringSchemaInterface,
371
+ Headers: HeadersSchemaInterface
372
+ }>({
373
+ method: 'GET',
374
+ url: '/auth2',
375
+ schema: {
376
+ querystring: QuerystringSchema,
377
+ headers: HeadersSchema
378
+ },
379
+ preHandler: (request, reply, done) => {
380
+ const { username, password } = request.query
381
+ const customerHeader = request.headers['h-Custom']
382
+ done()
383
+ },
384
+ handler: (request, reply) => {
385
+ const { username, password } = request.query
386
+ const customerHeader = request.headers['h-Custom']
387
+ reply.status(200).send({username});
388
+ }
389
+ })
390
+
391
+ server.listen({ port: 8080 }, (err, address) => {
392
+ if (err) {
393
+ console.error(err)
394
+ process.exit(0)
395
+ }
396
+ console.log(`Server listening at ${address}`)
397
+ })
398
+ ```
399
+ Pay special attention to the imports at the top of this file. It might seem
400
+ redundant, but you need to import both the schema files and the generated
401
+ interfaces.
402
+
403
+ Great work! Now you can make use of both JSON Schemas and TypeScript
404
+ definitions.
405
+
406
+ #### json-schema-to-ts
407
+
408
+ If you do not want to generate types from your schemas, but want to use them
409
+ directly from your code, you can use the package
410
+ [json-schema-to-ts](https://www.npmjs.com/package/json-schema-to-ts).
411
+
412
+ You can install it as dev-dependency.
413
+
414
+ ```bash
415
+ npm i -D json-schema-to-ts
416
+ ```
417
+
418
+ In your code you can define your schema like a normal object. But be aware of
419
+ making it *const* like explained in the docs of the module.
420
+
421
+ ```typescript
422
+ const todo = {
423
+ type: 'object',
424
+ properties: {
425
+ name: { type: 'string' },
426
+ description: { type: 'string' },
427
+ done: { type: 'boolean' },
428
+ },
429
+ required: ['name'],
430
+ } as const; // don't forget to use const !
431
+ ```
432
+
433
+ With the provided type `FromSchema` you can build a type from your schema and
434
+ use it in your handler.
435
+
436
+ ```typescript
437
+ import { FromSchema } from "json-schema-to-ts";
438
+ fastify.post<{ Body: FromSchema<typeof todo> }>(
439
+ '/todo',
440
+ {
441
+ schema: {
442
+ body: todo,
443
+ response: {
444
+ 201: {
445
+ type: 'string',
446
+ },
447
+ },
448
+ }
449
+ },
450
+ async (request, reply): Promise<void> => {
451
+
452
+ /*
453
+ request.body has type
454
+ {
455
+ [x: string]: unknown;
456
+ description?: string;
457
+ done?: boolean;
458
+ name: string;
459
+ }
460
+ */
461
+
462
+ request.body.name // will not throw type error
463
+ request.body.notthere // will throw type error
464
+
465
+ reply.status(201).send();
466
+ },
467
+ );
468
+ ```
469
+
470
+ ### Plugins
471
+
472
+ One of Fastify's most distinguishable features is its extensive plugin
473
+ ecosystem. Plugin types are fully supported, and take advantage of the
474
+ [declaration
475
+ merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)
476
+ pattern. This example is broken up into three parts: Creating a TypeScript
477
+ Fastify Plugin, Creating Type Definitions for a Fastify Plugin, and Using a
478
+ Fastify Plugin in a TypeScript Project.
479
+
480
+ #### Creating a TypeScript Fastify Plugin
481
+
482
+ 1. Initialize a new npm project and install required dependencies
483
+ ```bash
484
+ npm init -y
485
+ npm i fastify fastify-plugin
486
+ npm i -D typescript @types/node
487
+ ```
488
+ 2. Add a `build` script to the `"scripts"` section and `'index.d.ts'` to the
489
+ `"types"` section of the `package.json` file:
490
+ ```json
491
+ {
492
+ "types": "index.d.ts",
493
+ "scripts": {
494
+ "build": "tsc -p tsconfig.json"
495
+ }
496
+ }
497
+ ```
498
+ 3. Initialize a TypeScript configuration file:
499
+ ```bash
500
+ npx typescript --init
501
+ ```
502
+ Once the file is generated, enable the `"declaration"` option in the
503
+ `"compilerOptions"` object.
504
+ ```json
505
+ {
506
+ "compilerOptions": {
507
+ "declaration": true
508
+ }
509
+ }
510
+ ```
511
+ 4. Create an `index.ts` file - this will contain the plugin code
512
+ 5. Add the following code to `index.ts`
513
+ ```typescript
514
+ import { FastifyPluginCallback, FastifyPluginAsync } from 'fastify'
515
+ import fp from 'fastify-plugin'
516
+
517
+ // using declaration merging, add your plugin props to the appropriate fastify interfaces
518
+ // if prop type is defined here, the value will be typechecked when you call decorate{,Request,Reply}
519
+ declare module 'fastify' {
520
+ interface FastifyRequest {
521
+ myPluginProp: string
522
+ }
523
+ interface FastifyReply {
524
+ myPluginProp: number
525
+ }
526
+ }
527
+
528
+ // define options
529
+ export interface MyPluginOptions {
530
+ myPluginOption: string
531
+ }
532
+
533
+ // define plugin using callbacks
534
+ const myPluginCallback: FastifyPluginCallback<MyPluginOptions> = (fastify, options, done) => {
535
+ fastify.decorateRequest('myPluginProp', 'super_secret_value')
536
+ fastify.decorateReply('myPluginProp', options.myPluginOption)
537
+
538
+ done()
539
+ }
540
+
541
+ // define plugin using promises
542
+ const myPluginAsync: FastifyPluginAsync<MyPluginOptions> = async (fastify, options) => {
543
+ fastify.decorateRequest('myPluginProp', 'super_secret_value')
544
+ fastify.decorateReply('myPluginProp', options.myPluginOption)
545
+ }
546
+
547
+ // export plugin using fastify-plugin
548
+ export default fp(myPluginCallback, '3.x')
549
+ // or
550
+ // export default fp(myPluginAsync, '3.x')
551
+ ```
552
+ 6. Run `npm run build` to compile the plugin code and produce both a JavaScript
553
+ source file and a type definition file.
554
+ 7. With the plugin now complete you can [publish to npm] or use it locally.
555
+ > You do not _need_ to publish your plugin to npm to use it. You can include
556
+ > it in a Fastify project and reference it as you would any piece of code! As
557
+ > a TypeScript user, make sure the declaration override exists somewhere that
558
+ > will be included in your project compilation so the TypeScript interpreter
559
+ > can process it.
560
+
561
+ #### Creating Type Definitions for a Fastify Plugin
562
+
563
+ This plugin guide is for Fastify plugins written in JavaScript. The steps
564
+ outlined in this example are for adding TypeScript support for users consuming
565
+ your plugin.
566
+
567
+ 1. Initialize a new npm project and install required dependencies
568
+ ```bash
569
+ npm init -y
570
+ npm i fastify-plugin
571
+ ```
572
+ 2. Create two files `index.js` and `index.d.ts`
573
+ 3. Modify the package json to include these files under the `main` and `types`
574
+ properties (the name does not have to be `index` explicitly, but it is
575
+ recommended the files have the same name):
576
+ ```json
577
+ {
578
+ "main": "index.js",
579
+ "types": "index.d.ts"
580
+ }
581
+ ```
582
+ 4. Open `index.js` and add the following code:
583
+ ```javascript
584
+ // fastify-plugin is highly recommended for any plugin you write
585
+ const fp = require('fastify-plugin')
586
+
587
+ function myPlugin (instance, options, done) {
588
+
589
+ // decorate the fastify instance with a custom function called myPluginFunc
590
+ instance.decorate('myPluginFunc', (input) => {
591
+ return input.toUpperCase()
592
+ })
593
+
594
+ done()
595
+ }
596
+
597
+ module.exports = fp(myPlugin, {
598
+ fastify: '5.x',
599
+ name: 'my-plugin' // this is used by fastify-plugin to derive the property name
600
+ })
601
+ ```
602
+ 5. Open `index.d.ts` and add the following code:
603
+ ```typescript
604
+ import { FastifyPluginCallback } from 'fastify'
605
+
606
+ interface PluginOptions {
607
+ //...
608
+ }
609
+
610
+ // Optionally, you can add any additional exports.
611
+ // Here we are exporting the decorator we added.
612
+ export interface myPluginFunc {
613
+ (input: string): string
614
+ }
615
+
616
+ // Most importantly, use declaration merging to add the custom property to the Fastify type system
617
+ declare module 'fastify' {
618
+ interface FastifyInstance {
619
+ myPluginFunc: myPluginFunc
620
+ }
621
+ }
622
+
623
+ // fastify-plugin automatically adds named export, so be sure to add also this type
624
+ // the variable name is derived from `options.name` property if `module.exports.myPlugin` is missing
625
+ export const myPlugin: FastifyPluginCallback<PluginOptions>
626
+
627
+ // fastify-plugin automatically adds `.default` property to the exported plugin. See the note below
628
+ export default myPlugin
629
+ ```
630
+
631
+ __Note__: [fastify-plugin](https://github.com/fastify/fastify-plugin) v2.3.0 and
632
+ newer, automatically adds `.default` property and a named export to the exported
633
+ plugin. Be sure to `export default` and `export const myPlugin` in your typings
634
+ to provide the best developer experience. For a complete example you can check
635
+ out
636
+ [@fastify/swagger](https://github.com/fastify/fastify-swagger/blob/main/index.d.ts).
637
+
638
+ With those files completed, the plugin is now ready to be consumed by any
639
+ TypeScript project!
640
+
641
+ The Fastify plugin system enables developers to decorate the Fastify instance,
642
+ and the request/reply instances. For more information check out this blog post
643
+ on [Declaration Merging and Generic
644
+ Inheritance](https://dev.to/ethanarrowood/is-declaration-merging-and-generic-inheritance-at-the-same-time-impossible-53cp).
645
+
646
+ #### Using a Plugin
647
+
648
+ Using a Fastify plugin in TypeScript is just as easy as using one in JavaScript.
649
+ Import the plugin with `import/from` and you're all set -- except there is one
650
+ exception users should be aware of.
651
+
652
+ Fastify plugins use declaration merging to modify existing Fastify type
653
+ interfaces (check out the previous two examples for more details). Declaration
654
+ merging is not very _smart_, meaning if the plugin type definition for a plugin
655
+ is within the scope of the TypeScript interpreter, then the plugin types will be
656
+ included **regardless** of if the plugin is being used or not. This is an
657
+ unfortunate limitation of using TypeScript and is unavoidable as of right now.
658
+
659
+ However, there are a couple of suggestions to help improve this experience:
660
+ - Make sure the `no-unused-vars` rule is enabled in
661
+ [ESLint](https://eslint.org/docs/rules/no-unused-vars) and any imported plugin
662
+ are actually being loaded.
663
+ - Use a module such as [depcheck](https://www.npmjs.com/package/depcheck) or
664
+ [npm-check](https://www.npmjs.com/package/npm-check) to verify plugin
665
+ dependencies are being used somewhere in your project.
666
+
667
+ Note that using `require` will not load the type definitions properly and may
668
+ cause type errors.
669
+ TypeScript can only identify the types that are directly imported into code,
670
+ which means that you can use require inline with import on top. For example:
671
+
672
+ ```typescript
673
+ import 'plugin' // here will trigger the type augmentation.
674
+
675
+ fastify.register(require('plugin'))
676
+ ```
677
+
678
+ ```typescript
679
+ import plugin from 'plugin' // here will trigger the type augmentation.
680
+
681
+ fastify.register(plugin)
682
+ ```
683
+
684
+ Or even explicit config on tsconfig
685
+ ```jsonc
686
+ {
687
+ "types": ["plugin"] // we force TypeScript to import the types
688
+ }
689
+ ```
690
+
691
+ #### `getDecorator<T>`
692
+
693
+ Fastify's `getDecorator<T>` method retrieves decorators with enhanced type safety.
694
+
695
+ The `getDecorator<T>` method supports generic type parameters for enhanced type
696
+ safety:
697
+
698
+ ```typescript
699
+ // Type-safe decorator retrieval
700
+ const usersRepository = fastify.getDecorator<IUsersRepository>('usersRepository')
701
+ const session = request.getDecorator<ISession>('session')
702
+ const sendSuccess = reply.getDecorator<SendSuccessFn>('sendSuccess')
703
+ ```
704
+
705
+ **Alternative to Module Augmentation**
706
+
707
+ Decorators are typically typed via module augmentation:
708
+
709
+ ```typescript
710
+ declare module 'fastify' {
711
+ interface FastifyInstance {
712
+ usersRepository: IUsersRepository
713
+ }
714
+ interface FastifyRequest {
715
+ session: ISession
716
+ }
717
+ interface FastifyReply {
718
+ sendSuccess: SendSuccessFn
719
+ }
720
+ }
721
+ ```
722
+
723
+ This approach modifies the Fastify instance globally, which may lead to conflicts
724
+ and inconsistent behavior in multi-server setups or with plugin encapsulation.
725
+
726
+ Using `getDecorator<T>` allows limiting types scope:
727
+
728
+ ```typescript
729
+ serverOne.register(async function (fastify) {
730
+ const usersRepository = fastify.getDecorator<PostgreUsersRepository>(
731
+ 'usersRepository'
732
+ )
733
+
734
+ fastify.decorateRequest('session', null)
735
+ fastify.addHook('onRequest', async (req, reply) => {
736
+ req.setDecorator('session', { user: 'Jean' })
737
+ })
738
+
739
+ fastify.get('/me', (request, reply) => {
740
+ const session = request.getDecorator<ISession>('session')
741
+ reply.send(session)
742
+ })
743
+ })
744
+
745
+ serverTwo.register(async function (fastify) {
746
+ const usersRepository = fastify.getDecorator<SqlLiteUsersRepository>(
747
+ 'usersRepository'
748
+ )
749
+
750
+ fastify.decorateReply('sendSuccess', function (data) {
751
+ return this.send({ success: true })
752
+ })
753
+
754
+ fastify.get('/success', async (request, reply) => {
755
+ const sendSuccess = reply.getDecorator<SendSuccessFn>('sendSuccess')
756
+ await sendSuccess()
757
+ })
758
+ })
759
+ ```
760
+
761
+ **Bound Functions Inference**
762
+
763
+ To save time, it is common to infer function types instead of writing them manually:
764
+
765
+ ```typescript
766
+ function sendSuccess (this: FastifyReply) {
767
+ return this.send({ success: true })
768
+ }
769
+
770
+ export type SendSuccess = typeof sendSuccess
771
+ ```
772
+
773
+ However, `getDecorator` returns functions with the `this` context already **bound**,
774
+ meaning the `this` parameter disappears from the function signature.
775
+
776
+ To correctly type it, use the `OmitThisParameter` utility:
777
+
778
+ ```typescript
779
+ function sendSuccess (this: FastifyReply) {
780
+ return this.send({ success: true })
781
+ }
782
+
783
+ type BoundSendSuccess = OmitThisParameter<typeof sendSuccess>
784
+
785
+ fastify.decorateReply('sendSuccess', sendSuccess)
786
+ fastify.get('/success', async (request, reply) => {
787
+ const sendSuccess = reply.getDecorator<BoundSendSuccess>('sendSuccess')
788
+ await sendSuccess()
789
+ })
790
+ ```
791
+
792
+ #### `setDecorator<T>`
793
+
794
+ Fastify's `setDecorator<T>` method provides enhanced type safety for updating request
795
+ decorators.
796
+
797
+ The `setDecorator<T>` method provides enhanced type safety for updating request
798
+ decorators:
799
+
800
+ ```typescript
801
+ fastify.decorateRequest('user', '')
802
+ fastify.addHook('preHandler', async (req, reply) => {
803
+ // Type-safe decorator setting
804
+ req.setDecorator<string>('user', 'Bob Dylan')
805
+ })
806
+ ```
807
+
808
+ **Type Safety Benefits**
809
+
810
+ If the `FastifyRequest` interface does not declare the decorator, type assertions
811
+ are typically needed:
812
+
813
+ ```typescript
814
+ fastify.addHook('preHandler', async (req, reply) => {
815
+ (req as typeof req & { user: string }).user = 'Bob Dylan'
816
+ })
817
+ ```
818
+
819
+ The `setDecorator<T>` method eliminates the need for explicit type assertions
820
+ while providing type safety:
821
+
822
+ ```typescript
823
+ fastify.addHook('preHandler', async (req, reply) => {
824
+ req.setDecorator<string>('user', 'Bob Dylan')
825
+ })
826
+ ```
827
+
828
+ ## Code Completion In Vanilla JavaScript
829
+
830
+ Vanilla JavaScript can use the published types to provide code completion (e.g.
831
+ [Intellisense](https://code.visualstudio.com/docs/editor/intellisense)) by
832
+ following the [TypeScript JSDoc
833
+ Reference](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html).
834
+
835
+ For example:
836
+
837
+ ```js
838
+ /** @type {import('fastify').FastifyPluginAsync<{ optionA: boolean, optionB: string }>} */
839
+ module.exports = async function (fastify, { optionA, optionB }) {
840
+ fastify.get('/look', () => 'at me');
841
+ }
842
+ ```
843
+
844
+ ## API Type System Documentation
845
+
846
+ This section is a detailed account of all the types available to you in Fastify
847
+ version 3.x
848
+
849
+ All `http`, `https`, and `http2` types are inferred from `@types/node`
850
+
851
+ [Generics](#generics) are documented by their default value as well as their
852
+ constraint value(s). Read these articles for more information on TypeScript
853
+ generics.
854
+ - [Generic Parameter
855
+ Default](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#generic-parameter-defaults)
856
+ - [Generic Constraints](https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-constraints)
857
+
858
+
859
+ #### How to import
860
+
861
+ The Fastify API is powered by the `fastify()` method. In JavaScript you would
862
+ import it using `const fastify = require('fastify')`. In TypeScript it is
863
+ recommended to use the `import/from` syntax instead so types can be resolved.
864
+ There are a couple supported import methods with the Fastify type system.
865
+
866
+ 1. `import fastify from 'fastify'`
867
+ - Types are resolved but not accessible using dot notation
868
+ - Example:
869
+ ```typescript
870
+ import fastify from 'fastify'
871
+
872
+ const f = fastify()
873
+ f.listen({ port: 8080 }, () => { console.log('running') })
874
+ ```
875
+ - Gain access to types with destructuring:
876
+ ```typescript
877
+ import fastify, { FastifyInstance } from 'fastify'
878
+
879
+ const f: FastifyInstance = fastify()
880
+ f.listen({ port: 8080 }, () => { console.log('running') })
881
+ ```
882
+ - Destructuring also works for the main API method:
883
+ ```typescript
884
+ import { fastify, FastifyInstance } from 'fastify'
885
+
886
+ const f: FastifyInstance = fastify()
887
+ f.listen({ port: 8080 }, () => { console.log('running') })
888
+ ```
889
+ 2. `import * as Fastify from 'fastify'`
890
+ - Types are resolved and accessible using dot notation
891
+ - Calling the main Fastify API method requires a slightly different syntax
892
+ (see example)
893
+ - Example:
894
+ ```typescript
895
+ import * as Fastify from 'fastify'
896
+
897
+ const f: Fastify.FastifyInstance = Fastify.fastify()
898
+ f.listen({ port: 8080 }, () => { console.log('running') })
899
+ ```
900
+ 3. `const fastify = require('fastify')`
901
+ - This syntax is valid and will import fastify as expected; however, types
902
+ will **not** be resolved
903
+ - Example:
904
+ ```typescript
905
+ const fastify = require('fastify')
906
+
907
+ const f = fastify()
908
+ f.listen({ port: 8080 }, () => { console.log('running') })
909
+ ```
910
+ - Destructuring is supported and will resolve types properly
911
+ ```typescript
912
+ const { fastify } = require('fastify')
913
+
914
+ const f = fastify()
915
+ f.listen({ port: 8080 }, () => { console.log('running') })
916
+ ```
917
+
918
+ #### Generics
919
+
920
+ Many type definitions share the same generic parameters; they are all
921
+ documented, in detail, within this section.
922
+
923
+ Most definitions depend on `@types/node` modules `http`, `https`, and `http2`
924
+
925
+ ##### RawServer
926
+ Underlying Node.js server type
927
+
928
+ Default: `http.Server`
929
+
930
+ Constraints: `http.Server`, `https.Server`, `http2.Http2Server`,
931
+ `http2.Http2SecureServer`
932
+
933
+ Enforces generic parameters: [`RawRequest`][RawRequestGeneric],
934
+ [`RawReply`][RawReplyGeneric]
935
+
936
+ ##### RawRequest
937
+ Underlying Node.js request type
938
+
939
+ Default: [`RawRequestDefaultExpression`][RawRequestDefaultExpression]
940
+
941
+ Constraints: `http.IncomingMessage`, `http2.Http2ServerRequest`
942
+
943
+ Enforced by: [`RawServer`][RawServerGeneric]
944
+
945
+ ##### RawReply
946
+ Underlying Node.js response type
947
+
948
+ Default: [`RawReplyDefaultExpression`][RawReplyDefaultExpression]
949
+
950
+ Constraints: `http.ServerResponse`, `http2.Http2ServerResponse`
951
+
952
+ Enforced by: [`RawServer`][RawServerGeneric]
953
+
954
+ ##### Logger
955
+ Fastify logging utility
956
+
957
+ Default: [`FastifyLoggerOptions`][FastifyLoggerOptions]
958
+
959
+ Enforced by: [`RawServer`][RawServerGeneric]
960
+
961
+ ##### RawBody
962
+ A generic parameter for the content-type-parser methods.
963
+
964
+ Constraints: `string | Buffer`
965
+
966
+ ---
967
+
968
+ #### Fastify
969
+
970
+ ##### fastify< [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [Logger][LoggerGeneric]>(opts?: [FastifyServerOptions][FastifyServerOptions]): [FastifyInstance][FastifyInstance]
971
+ [src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L19)
972
+
973
+ The main Fastify API method. By default creates an HTTP server. Utilizing
974
+ discriminant unions and overload methods, the type system will automatically
975
+ infer which type of server (http, https, or http2) is being created purely based
976
+ on the options based to the method (see the examples below for more
977
+ information). It also supports an extensive generic type system to allow the
978
+ user to extend the underlying Node.js Server, Request, and Reply objects.
979
+ Additionally, the `Logger` generic exists for custom log types. See the examples
980
+ and generic breakdown below for more information.
981
+
982
+ ###### Example 1: Standard HTTP server
983
+
984
+ No need to specify the `Server` generic as the type system defaults to HTTP.
985
+ ```typescript
986
+ import fastify from 'fastify'
987
+
988
+ const server = fastify()
989
+ ```
990
+ Check out the Learn By Example - [Getting Started](#getting-started) example for
991
+ a more detailed http server walkthrough.
992
+
993
+ ###### Example 2: HTTPS server
994
+
995
+ 1. Create the following imports from `@types/node` and `fastify`
996
+ ```typescript
997
+ import fs from 'node:fs'
998
+ import path from 'node:path'
999
+ import fastify from 'fastify'
1000
+ ```
1001
+ 2. Perform the following steps before setting up a Fastify HTTPS server
1002
+ to create the `key.pem` and `cert.pem` files:
1003
+ ```sh
1004
+ openssl genrsa -out key.pem
1005
+ openssl req -new -key key.pem -out csr.pem
1006
+ openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
1007
+ rm csr.pem
1008
+ ```
1009
+ 3. Instantiate a Fastify https server and add a route:
1010
+ ```typescript
1011
+ const server = fastify({
1012
+ https: {
1013
+ key: fs.readFileSync(path.join(__dirname, 'key.pem')),
1014
+ cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))
1015
+ }
1016
+ })
1017
+
1018
+ server.get('/', async function (request, reply) {
1019
+ return { hello: 'world' }
1020
+ })
1021
+
1022
+ server.listen({ port: 8080 }, (err, address) => {
1023
+ if (err) {
1024
+ console.error(err)
1025
+ process.exit(0)
1026
+ }
1027
+ console.log(`Server listening at ${address}`)
1028
+ })
1029
+ ```
1030
+ 4. Build and run! Test your server out by querying with: `curl -k
1031
+ https://localhost:8080`
1032
+
1033
+ ###### Example 3: HTTP2 server
1034
+
1035
+ There are two types of HTTP2 server types, insecure and secure. Both require
1036
+ specifying the `http2` property as `true` in the `options` object. The `https`
1037
+ property is used for creating a secure http2 server; omitting the `https`
1038
+ property will create an insecure http2 server.
1039
+
1040
+ ```typescript
1041
+ const insecureServer = fastify({ http2: true })
1042
+ const secureServer = fastify({
1043
+ http2: true,
1044
+ https: {} // use the `key.pem` and `cert.pem` files from the https section
1045
+ })
1046
+ ```
1047
+
1048
+ For more details on using HTTP2 check out the Fastify [HTTP2](./HTTP2.md)
1049
+ documentation page.
1050
+
1051
+ ###### Example 4: Extended HTTP server
1052
+
1053
+ Not only can you specify the server type, but also the request and reply types.
1054
+ Thus, allowing you to specify special properties, methods, and more! When
1055
+ specified at server instantiation, the custom type becomes available on all
1056
+ further instances of the custom type.
1057
+ ```typescript
1058
+ import fastify from 'fastify'
1059
+ import http from 'node:http'
1060
+
1061
+ interface customRequest extends http.IncomingMessage {
1062
+ mySpecialProp: string
1063
+ }
1064
+
1065
+ const server = fastify<http.Server, customRequest>()
1066
+
1067
+ server.get('/', async (request, reply) => {
1068
+ const someValue = request.raw.mySpecialProp // TS knows this is a string, because of the `customRequest` interface
1069
+ return someValue.toUpperCase()
1070
+ })
1071
+ ```
1072
+
1073
+ ###### Example 5: Specifying logger types
1074
+
1075
+ Fastify uses [Pino](https://getpino.io/#/) logging library under the hood. Since
1076
+ `pino@7`, all of it's properties can be configured via `logger` field when
1077
+ constructing Fastify's instance. If properties you need aren't exposed, please
1078
+ open an Issue to [`Pino`](https://github.com/pinojs/pino/issues) or pass a
1079
+ preconfigured external instance of Pino (or any other compatible logger) as
1080
+ temporary fix to Fastify via the same field. This allows creating custom
1081
+ serializers as well, see the [Logging](Logging.md) documentation for more info.
1082
+
1083
+ ```typescript
1084
+ import fastify from 'fastify'
1085
+
1086
+ const server = fastify({
1087
+ logger: {
1088
+ level: 'info',
1089
+ redact: ['x-userinfo'],
1090
+ messageKey: 'message'
1091
+ }
1092
+ })
1093
+
1094
+ server.get('/', async (request, reply) => {
1095
+ server.log.info('log message')
1096
+ return 'another message'
1097
+ })
1098
+ ```
1099
+
1100
+ ---
1101
+
1102
+ ##### fastify.HTTPMethods
1103
+ [src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L8)
1104
+
1105
+ Union type of: `'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' |
1106
+ 'OPTIONS'`
1107
+
1108
+ ##### fastify.RawServerBase
1109
+ [src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L13)
1110
+
1111
+ Dependent on `@types/node` modules `http`, `https`, `http2`
1112
+
1113
+ Union type of: `http.Server | https.Server | http2.Http2Server |
1114
+ http2.Http2SecureServer`
1115
+
1116
+ ##### fastify.RawServerDefault
1117
+ [src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L18)
1118
+
1119
+ Dependent on `@types/node` modules `http`
1120
+
1121
+ Type alias for `http.Server`
1122
+
1123
+ ---
1124
+
1125
+ ##### fastify.FastifyServerOptions< [RawServer][RawServerGeneric], [Logger][LoggerGeneric]>
1126
+
1127
+ [src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L29)
1128
+
1129
+ An interface of properties used in the instantiation of the Fastify server. Is
1130
+ used in the main [`fastify()`][Fastify] method. The `RawServer` and `Logger`
1131
+ generic parameters are passed down through that method.
1132
+
1133
+ See the main [fastify][Fastify] method type definition section for examples on
1134
+ instantiating a Fastify server with TypeScript.
1135
+
1136
+ ##### fastify.FastifyInstance< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RequestGeneric][FastifyRequestGenericInterface], [Logger][LoggerGeneric]>
1137
+
1138
+ [src](https://github.com/fastify/fastify/blob/main/types/instance.d.ts#L16)
1139
+
1140
+ Interface that represents the Fastify server object. This is the returned server
1141
+ instance from the [`fastify()`][Fastify] method. This type is an interface so it
1142
+ can be extended via [declaration
1143
+ merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)
1144
+ if your code makes use of the `decorate` method.
1145
+
1146
+ Through the use of generic cascading, all methods attached to the instance
1147
+ inherit the generic properties from instantiation. This means that by specifying
1148
+ the server, request, or reply types, all methods will know how to type those
1149
+ objects.
1150
+
1151
+ Check out the main [Learn by Example](#learn-by-example) section for detailed
1152
+ guides, or the more simplified [fastify][Fastify] method examples for additional
1153
+ details on this interface.
1154
+
1155
+ ---
1156
+
1157
+ #### Request
1158
+
1159
+ ##### fastify.FastifyRequest< [RequestGeneric][FastifyRequestGenericInterface], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>
1160
+ [src](https://github.com/fastify/fastify/blob/main/types/request.d.ts#L15)
1161
+
1162
+ This interface contains properties of Fastify request object. The properties
1163
+ added here disregard what kind of request object (http vs http2) and disregard
1164
+ what route level it is serving; thus calling `request.body` inside a GET request
1165
+ will not throw an error (but good luck sending a GET request with a body 😉).
1166
+
1167
+ If you need to add custom properties to the `FastifyRequest` object (such as
1168
+ when using the [`decorateRequest`][DecorateRequest] method) you need to use
1169
+ declaration merging on this interface.
1170
+
1171
+ A basic example is provided in the [`FastifyRequest`][FastifyRequest] section.
1172
+ For a more detailed example check out the Learn By Example section:
1173
+ [Plugins](#plugins)
1174
+
1175
+ ###### Example
1176
+ ```typescript
1177
+ import fastify from 'fastify'
1178
+
1179
+ const server = fastify()
1180
+
1181
+ server.decorateRequest('someProp', 'hello!')
1182
+
1183
+ server.get('/', async (request, reply) => {
1184
+ const { someProp } = request // need to use declaration merging to add this prop to the request interface
1185
+ return someProp
1186
+ })
1187
+
1188
+ // this declaration must be in scope of the typescript interpreter to work
1189
+ declare module 'fastify' {
1190
+ interface FastifyRequest { // you must reference the interface and not the type
1191
+ someProp: string
1192
+ }
1193
+ }
1194
+
1195
+ // Or you can type your request using
1196
+ type CustomRequest = FastifyRequest<{
1197
+ Body: { test: boolean };
1198
+ }>
1199
+
1200
+ server.get('/typedRequest', async (request: CustomRequest, reply: FastifyReply) => {
1201
+ return request.body.test
1202
+ })
1203
+ ```
1204
+
1205
+ ##### fastify.RequestGenericInterface
1206
+ [src](https://github.com/fastify/fastify/blob/main/types/request.d.ts#L4)
1207
+
1208
+ Fastify request objects have four dynamic properties: `body`, `params`, `query`,
1209
+ and `headers`. Their respective types are assignable through this interface. It
1210
+ is a named property interface enabling the developer to ignore the properties
1211
+ they do not want to specify. All omitted properties are defaulted to `unknown`.
1212
+ The corresponding property names are: `Body`, `Querystring`, `Params`,
1213
+ `Headers`.
1214
+
1215
+ ```typescript
1216
+ import fastify, { RequestGenericInterface } from 'fastify'
1217
+
1218
+ const server = fastify()
1219
+
1220
+ interface requestGeneric extends RequestGenericInterface {
1221
+ Querystring: {
1222
+ name: string
1223
+ }
1224
+ }
1225
+
1226
+ server.get<requestGeneric>('/', async (request, reply) => {
1227
+ const { name } = request.query // the name prop now exists on the query prop
1228
+ return name.toUpperCase()
1229
+ })
1230
+ ```
1231
+
1232
+ If you want to see a detailed example of using this interface check out the
1233
+ Learn by Example section: [JSON Schema](#json-schema).
1234
+
1235
+ ##### fastify.RawRequestDefaultExpression\<[RawServer][RawServerGeneric]\>
1236
+ [src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L23)
1237
+
1238
+ Dependent on `@types/node` modules `http`, `https`, `http2`
1239
+
1240
+ Generic parameter `RawServer` defaults to [`RawServerDefault`][RawServerDefault]
1241
+
1242
+ If `RawServer` is of type `http.Server` or `https.Server`, then this expression
1243
+ returns `http.IncomingMessage`, otherwise, it returns
1244
+ `http2.Http2ServerRequest`.
1245
+
1246
+ ```typescript
1247
+ import http from 'node:http'
1248
+ import http2 from 'node:http2'
1249
+ import { RawRequestDefaultExpression } from 'fastify'
1250
+
1251
+ RawRequestDefaultExpression<http.Server> // -> http.IncomingMessage
1252
+ RawRequestDefaultExpression<http2.Http2Server> // -> http2.Http2ServerRequest
1253
+ ```
1254
+
1255
+ ---
1256
+
1257
+ #### Reply
1258
+
1259
+ ##### fastify.FastifyReply<[RequestGeneric][FastifyRequestGenericInterface], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [ContextConfig][ContextConfigGeneric]>
1260
+ [src](https://github.com/fastify/fastify/blob/main/types/reply.d.ts#L32)
1261
+
1262
+ This interface contains the custom properties that Fastify adds to the standard
1263
+ Node.js reply object. The properties added here disregard what kind of reply
1264
+ object (http vs http2).
1265
+
1266
+ If you need to add custom properties to the FastifyReply object (such as when
1267
+ using the `decorateReply` method) you need to use declaration merging on this
1268
+ interface.
1269
+
1270
+ A basic example is provided in the [`FastifyReply`][FastifyReply] section. For a
1271
+ more detailed example check out the Learn By Example section:
1272
+ [Plugins](#plugins)
1273
+
1274
+ ###### Example
1275
+ ```typescript
1276
+ import fastify from 'fastify'
1277
+
1278
+ const server = fastify()
1279
+
1280
+ server.decorateReply('someProp', 'world')
1281
+
1282
+ server.get('/', async (request, reply) => {
1283
+ const { someProp } = reply // need to use declaration merging to add this prop to the reply interface
1284
+ return someProp
1285
+ })
1286
+
1287
+ // this declaration must be in scope of the typescript interpreter to work
1288
+ declare module 'fastify' {
1289
+ interface FastifyReply { // you must reference the interface and not the type
1290
+ someProp: string
1291
+ }
1292
+ }
1293
+ ```
1294
+
1295
+ ##### fastify.RawReplyDefaultExpression< [RawServer][RawServerGeneric]>
1296
+ [src](https://github.com/fastify/fastify/blob/main/types/utils.d.ts#L27)
1297
+
1298
+ Dependent on `@types/node` modules `http`, `https`, `http2`
1299
+
1300
+ Generic parameter `RawServer` defaults to [`RawServerDefault`][RawServerDefault]
1301
+
1302
+ If `RawServer` is of type `http.Server` or `https.Server`, then this expression
1303
+ returns `http.ServerResponse`, otherwise, it returns
1304
+ `http2.Http2ServerResponse`.
1305
+
1306
+ ```typescript
1307
+ import http from 'node:http'
1308
+ import http2 from 'node:http2'
1309
+ import { RawReplyDefaultExpression } from 'fastify'
1310
+
1311
+ RawReplyDefaultExpression<http.Server> // -> http.ServerResponse
1312
+ RawReplyDefaultExpression<http2.Http2Server> // -> http2.Http2ServerResponse
1313
+ ```
1314
+
1315
+ ---
1316
+
1317
+ #### Plugin
1318
+
1319
+ Fastify allows the user to extend its functionalities with plugins. A plugin can
1320
+ be a set of routes, a server decorator or whatever. To activate plugins, use the
1321
+ [`fastify.register()`][FastifyRegister] method.
1322
+
1323
+ When creating plugins for Fastify, it is recommended to use the `fastify-plugin`
1324
+ module. Additionally, there is a guide to creating plugins with TypeScript and
1325
+ Fastify available in the Learn by Example, [Plugins](#plugins) section.
1326
+
1327
+ ##### fastify.FastifyPluginCallback< [Options][FastifyPluginOptions]>
1328
+ [src](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L9)
1329
+
1330
+ Interface method definition used within the
1331
+ [`fastify.register()`][FastifyRegister] method.
1332
+
1333
+ ##### fastify.FastifyPluginAsync< [Options][FastifyPluginOptions]>
1334
+ [src](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L20)
1335
+
1336
+ Interface method definition used within the
1337
+ [`fastify.register()`][FastifyRegister] method.
1338
+
1339
+ ##### fastify.FastifyPlugin< [Options][FastifyPluginOptions]>
1340
+ [src](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L29)
1341
+
1342
+ Interface method definition used within the
1343
+ [`fastify.register()`][FastifyRegister] method. Document deprecated in favor of
1344
+ `FastifyPluginCallback` and `FastifyPluginAsync` since general `FastifyPlugin`
1345
+ doesn't properly infer types for async functions.
1346
+
1347
+ ##### fastify.FastifyPluginOptions
1348
+ [src](https://github.com/fastify/fastify/blob/main/types/plugin.d.ts#L31)
1349
+
1350
+ A loosely typed object used to constrain the `options` parameter of
1351
+ [`fastify.register()`][FastifyRegister] to an object. When creating a plugin,
1352
+ define its options as an extension of this interface (`interface MyPluginOptions
1353
+ extends FastifyPluginOptions`) so they can be passed to the register method.
1354
+
1355
+ ---
1356
+
1357
+ #### Register
1358
+
1359
+ ##### fastify.FastifyRegister(plugin: [FastifyPluginCallback][FastifyPluginCallback], opts: [FastifyRegisterOptions][FastifyRegisterOptions])
1360
+ [src](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L9)
1361
+ ##### fastify.FastifyRegister(plugin: [FastifyPluginAsync][FastifyPluginAsync], opts: [FastifyRegisterOptions][FastifyRegisterOptions])
1362
+ [src](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L9)
1363
+ ##### fastify.FastifyRegister(plugin: [FastifyPlugin][FastifyPlugin], opts: [FastifyRegisterOptions][FastifyRegisterOptions])
1364
+ [src](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L9)
1365
+
1366
+ This type interface specifies the type for the
1367
+ [`fastify.register()`](./Server.md#register) method. The type interface returns
1368
+ a function signature with an underlying generic `Options` which is defaulted to
1369
+ [FastifyPluginOptions][FastifyPluginOptions]. It infers this generic from the
1370
+ FastifyPlugin parameter when calling this function so there is no need to
1371
+ specify the underlying generic. The options parameter is the intersection of the
1372
+ plugin's options and two additional optional properties: `prefix: string` and
1373
+ `logLevel`: [LogLevel][LogLevel]. `FastifyPlugin` is deprecated use
1374
+ `FastifyPluginCallback` and `FastifyPluginAsync` instead.
1375
+
1376
+ Below is an example of the options inference in action:
1377
+
1378
+ ```typescript
1379
+ const server = fastify()
1380
+
1381
+ const plugin: FastifyPluginCallback<{
1382
+ option1: string;
1383
+ option2: boolean;
1384
+ }> = function (instance, opts, done) { }
1385
+
1386
+ server().register(plugin, {}) // Error - options object is missing required properties
1387
+ server().register(plugin, { option1: '', option2: true }) // OK - options object contains required properties
1388
+ ```
1389
+
1390
+ See the Learn By Example, [Plugins](#plugins) section for more detailed examples
1391
+ of creating TypeScript plugins in Fastify.
1392
+
1393
+ ##### fastify.FastifyRegisterOptions
1394
+ [src](https://github.com/fastify/fastify/blob/main/types/register.d.ts#L16)
1395
+
1396
+ This type is the intersection of the `Options` generic and a non-exported
1397
+ interface `RegisterOptions` that specifies two optional properties: `prefix:
1398
+ string` and `logLevel`: [LogLevel][LogLevel]. This type can also be specified as
1399
+ a function that returns the previously described intersection.
1400
+
1401
+ ---
1402
+
1403
+ #### Logger
1404
+
1405
+ Check out the [Specifying Logger Types](#example-5-specifying-logger-types)
1406
+ example for more details on specifying a custom logger.
1407
+
1408
+ ##### fastify.FastifyLoggerOptions< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric]>
1409
+
1410
+ [src](https://github.com/fastify/fastify/blob/main/types/logger.d.ts#L17)
1411
+
1412
+ An interface definition for the internal Fastify logger. It is emulative of the
1413
+ [Pino.js](https://getpino.io/#/) logger. When enabled through server options,
1414
+ use it following the general [logger](./Logging.md) documentation.
1415
+
1416
+ ##### fastify.FastifyLogFn
1417
+
1418
+ [src](https://github.com/fastify/fastify/blob/main/types/logger.d.ts#L7)
1419
+
1420
+ An overload function interface that implements the two ways Fastify calls log
1421
+ methods. This interface is passed to all associated log level properties on the
1422
+ FastifyLoggerOptions object.
1423
+
1424
+ ##### fastify.LogLevel
1425
+
1426
+ [src](https://github.com/fastify/fastify/blob/main/types/logger.d.ts#L12)
1427
+
1428
+ Union type of: `'info' | 'error' | 'debug' | 'fatal' | 'warn' | 'trace'`
1429
+
1430
+ ---
1431
+
1432
+ #### Context
1433
+
1434
+ The context type definition is similar to the other highly dynamic pieces of the
1435
+ type system. Route context is available in the route handler method.
1436
+
1437
+ ##### fastify.FastifyRequestContext
1438
+
1439
+ [src](https://github.com/fastify/fastify/blob/main/types/context.d.ts#L11)
1440
+
1441
+ An interface with a single required property `config` that is set by default to
1442
+ `unknown`. Can be specified either using a generic or an overload.
1443
+
1444
+ This type definition is potentially incomplete. If you are using it and can
1445
+ provide more details on how to improve the definition, we strongly encourage you
1446
+ to open an issue in the main
1447
+ [fastify/fastify](https://github.com/fastify/fastify) repository. Thank you in
1448
+ advanced!
1449
+
1450
+ ##### fastify.FastifyReplyContext
1451
+
1452
+ [src](https://github.com/fastify/fastify/blob/main/types/context.d.ts#L11)
1453
+
1454
+ An interface with a single required property `config` that is set by default to
1455
+ `unknown`. Can be specified either using a generic or an overload.
1456
+
1457
+ This type definition is potentially incomplete. If you are using it and can
1458
+ provide more details on how to improve the definition, we strongly encourage you
1459
+ to open an issue in the main
1460
+ [fastify/fastify](https://github.com/fastify/fastify) repository. Thank you in
1461
+ advanced!
1462
+
1463
+ ---
1464
+
1465
+ #### Routing
1466
+
1467
+ One of the core principles in Fastify is its routing capabilities. Most of the
1468
+ types defined in this section are used under-the-hood by the Fastify instance
1469
+ `.route` and `.get/.post/.etc` methods.
1470
+
1471
+ ##### fastify.RouteHandlerMethod< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>
1472
+
1473
+ [src](https://github.com/fastify/fastify/blob/main/types/route.d.ts#L105)
1474
+
1475
+ A type declaration for the route handler methods. Has two arguments, `request`
1476
+ and `reply` which are typed by `FastifyRequest` and `FastifyReply` respectively.
1477
+ The generics parameters are passed through to these arguments. The method
1478
+ returns either `void` or `Promise<any>` for synchronous and asynchronous
1479
+ handlers respectively.
1480
+
1481
+ ##### fastify.RouteOptions< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>
1482
+
1483
+ [src](https://github.com/fastify/fastify/blob/main/types/route.d.ts#L78)
1484
+
1485
+ An interface that extends RouteShorthandOptions and adds the following three
1486
+ required properties:
1487
+ 1. `method` which corresponds to a singular [HTTPMethod][HTTPMethods] or a list
1488
+ of [HTTPMethods][HTTPMethods]
1489
+ 2. `url` a string for the route
1490
+ 3. `handler` the route handler method, see [RouteHandlerMethod][] for more
1491
+ details
1492
+
1493
+ ##### fastify.RouteShorthandMethod< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric]>
1494
+
1495
+ [src](https://github.com/fastify/fastify/blob/main/types/route.d.ts#12)
1496
+
1497
+ An overloaded function interface for three kinds of shorthand route methods to
1498
+ be used in conjunction with the `.get/.post/.etc` methods.
1499
+
1500
+ ##### fastify.RouteShorthandOptions< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>
1501
+
1502
+ [src](https://github.com/fastify/fastify/blob/main/types/route.d.ts#55)
1503
+
1504
+ An interface that covers all of the base options for a route. Each property on
1505
+ this interface is optional, and it serves as the base for the RouteOptions and
1506
+ RouteShorthandOptionsWithHandler interfaces.
1507
+
1508
+ ##### fastify.RouteShorthandOptionsWithHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>
1509
+
1510
+ [src](https://github.com/fastify/fastify/blob/main/types/route.d.ts#93)
1511
+
1512
+ This interface adds a single, required property to the RouteShorthandOptions
1513
+ interface `handler` which is of type RouteHandlerMethod
1514
+
1515
+ ---
1516
+
1517
+ #### Parsers
1518
+
1519
+ ##### RawBody
1520
+
1521
+ A generic type that is either a `string` or `Buffer`
1522
+
1523
+ ##### fastify.FastifyBodyParser< [RawBody][RawBodyGeneric], [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>
1524
+
1525
+ [src](https://github.com/fastify/fastify/blob/main/types/content-type-parser.d.ts#L7)
1526
+
1527
+ A function type definition for specifying a body parser method. Use the
1528
+ `RawBody` generic to specify the type of the body being parsed.
1529
+
1530
+ ##### fastify.FastifyContentTypeParser< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>
1531
+
1532
+ [src](https://github.com/fastify/fastify/blob/main/types/content-type-parser.d.ts#L17)
1533
+
1534
+ A function type definition for specifying a body parser method. Content is typed
1535
+ via the `RawRequest` generic.
1536
+
1537
+ ##### fastify.AddContentTypeParser< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric]>
1538
+
1539
+ [src](https://github.com/fastify/fastify/blob/main/types/content-type-parser.d.ts#L46)
1540
+
1541
+ An overloaded interface function definition for the `addContentTypeParser`
1542
+ method. If `parseAs` is passed to the `opts` parameter, the definition uses
1543
+ [FastifyBodyParser][] for the `parser` parameter; otherwise, it uses
1544
+ [FastifyContentTypeParser][].
1545
+
1546
+ ##### fastify.hasContentTypeParser
1547
+
1548
+ [src](https://github.com/fastify/fastify/blob/main/types/content-type-parser.d.ts#L63)
1549
+
1550
+ A method for checking the existence of a type parser of a certain content type
1551
+
1552
+ ---
1553
+
1554
+ #### Errors
1555
+
1556
+ ##### fastify.FastifyError
1557
+
1558
+ [src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L179)
1559
+
1560
+ FastifyError is a custom error object that includes status code and validation
1561
+ results.
1562
+
1563
+ It extends the Node.js `Error` type, and adds two additional, optional
1564
+ properties: `statusCode: number` and `validation: ValidationResult[]`.
1565
+
1566
+ ##### fastify.ValidationResult
1567
+
1568
+ [src](https://github.com/fastify/fastify/blob/main/fastify.d.ts#L184)
1569
+
1570
+ The route validation internally relies upon Ajv, which is a high-performance
1571
+ JSON schema validator.
1572
+
1573
+ This interface is passed to instance of FastifyError.
1574
+
1575
+ ---
1576
+
1577
+ #### Hooks
1578
+
1579
+ ##### fastify.onRequestHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1580
+
1581
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L17)
1582
+
1583
+ `onRequest` is the first hook to be executed in the request lifecycle. There was
1584
+ no previous hook, the next hook will be `preParsing`.
1585
+
1586
+ Notice: in the `onRequest` hook, request.body will always be null, because the
1587
+ body parsing happens before the `preHandler` hook.
1588
+
1589
+ ##### fastify.preParsingHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1590
+
1591
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L35)
1592
+
1593
+ `preParsing` is the second hook to be executed in the request lifecycle. The
1594
+ previous hook was `onRequest`, the next hook will be `preValidation`.
1595
+
1596
+ Notice: in the `preParsing` hook, request.body will always be null, because the
1597
+ body parsing happens before the `preValidation` hook.
1598
+
1599
+ Notice: you should also add `receivedEncodedLength` property to the returned
1600
+ stream. This property is used to correctly match the request payload with the
1601
+ `Content-Length` header value. Ideally, this property should be updated on each
1602
+ received chunk.
1603
+
1604
+ ##### fastify.preValidationHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1605
+
1606
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L53)
1607
+
1608
+ `preValidation` is the third hook to be executed in the request lifecycle. The
1609
+ previous hook was `preParsing`, the next hook will be `preHandler`.
1610
+
1611
+ ##### fastify.preHandlerHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1612
+
1613
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L70)
1614
+
1615
+ `preHandler` is the fourth hook to be executed in the request lifecycle. The
1616
+ previous hook was `preValidation`, the next hook will be `preSerialization`.
1617
+
1618
+ ##### fastify.preSerializationHookHandler< PreSerializationPayload, [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], payload: PreSerializationPayload, done: (err: [FastifyError][FastifyError] | null, res?: unknown) => void): Promise\<unknown\> | void
1619
+
1620
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L94)
1621
+
1622
+ `preSerialization` is the fifth hook to be executed in the request lifecycle.
1623
+ The previous hook was `preHandler`, the next hook will be `onSend`.
1624
+
1625
+ > ℹ️ Note:
1626
+ > The hook is NOT called if the payload is a string, a Buffer,
1627
+ > a stream, or null.
1628
+
1629
+ ##### fastify.onSendHookHandler< OnSendPayload, [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], payload: OnSendPayload, done: (err: [FastifyError][FastifyError] | null, res?: unknown) => void): Promise\<unknown\> | void
1630
+
1631
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L114)
1632
+
1633
+ You can change the payload with the `onSend` hook. It is the sixth hook to be
1634
+ executed in the request lifecycle. The previous hook was `preSerialization`, the
1635
+ next hook will be `onResponse`.
1636
+
1637
+ > ℹ️ Note:
1638
+ > If you change the payload, you may only change it to a string,
1639
+ > a Buffer, a stream, or null.
1640
+
1641
+ ##### fastify.onResponseHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1642
+
1643
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L134)
1644
+
1645
+ `onResponse` is the seventh and last hook in the request hook lifecycle. The
1646
+ previous hook was `onSend`, there is no next hook.
1647
+
1648
+ The onResponse hook is executed when a response has been sent, so you will not
1649
+ be able to send more data to the client. It can however be useful for sending
1650
+ data to external services, for example to gather statistics.
1651
+
1652
+ ##### fastify.onErrorHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(request: [FastifyRequest][FastifyRequest], reply: [FastifyReply][FastifyReply], error: [FastifyError][FastifyError], done: () => void): Promise\<unknown\> | void
1653
+
1654
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L154)
1655
+
1656
+ This hook is useful if you need to do some custom error logging or add some
1657
+ specific header in case of error.
1658
+
1659
+ It is not intended for changing the error, and calling reply.send will throw an
1660
+ exception.
1661
+
1662
+ This hook will be executed before the customErrorHandler.
1663
+
1664
+ Notice: unlike the other hooks, pass an error to the done function is not
1665
+ supported.
1666
+
1667
+ ##### fastify.onRouteHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [RequestGeneric][FastifyRequestGenericInterface], [ContextConfig][ContextConfigGeneric]>(opts: [RouteOptions][RouteOptions] & \{ path: string; prefix: string }): Promise\<unknown\> | void
1668
+
1669
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L174)
1670
+
1671
+ Triggered when a new route is registered. Listeners are passed a routeOptions
1672
+ object as the sole parameter. The interface is synchronous, and, as such, the
1673
+ listener does not get passed a callback
1674
+
1675
+ ##### fastify.onRegisterHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [Logger][LoggerGeneric]>(instance: [FastifyInstance][FastifyInstance], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1676
+
1677
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L191)
1678
+
1679
+ Triggered when a new plugin is registered and a new encapsulation context is
1680
+ created. The hook will be executed before the registered code.
1681
+
1682
+ This hook can be useful if you are developing a plugin that needs to know when a
1683
+ plugin context is formed, and you want to operate in that specific context.
1684
+
1685
+ > ℹ️ Note:
1686
+ > This hook will not be called if a plugin is wrapped inside fastify-plugin.
1687
+
1688
+ ##### fastify.onCloseHookHandler< [RawServer][RawServerGeneric], [RawRequest][RawRequestGeneric], [RawReply][RawReplyGeneric], [Logger][LoggerGeneric]>(instance: [FastifyInstance][FastifyInstance], done: (err?: [FastifyError][FastifyError]) => void): Promise\<unknown\> | void
1689
+
1690
+ [src](https://github.com/fastify/fastify/blob/main/types/hooks.d.ts#L206)
1691
+
1692
+ Triggered when fastify.close() is invoked to stop the server. It is useful when
1693
+ plugins need a "shutdown" event, for example to close an open connection to a
1694
+ database.
1695
+
1696
+
1697
+ <!-- Links -->
1698
+
1699
+ [Fastify]:
1700
+ #fastifyrawserver-rawrequest-rawreply-loggeropts-fastifyserveroptions-fastifyinstance
1701
+ [RawServerGeneric]: #rawserver
1702
+ [RawRequestGeneric]: #rawrequest
1703
+ [RawReplyGeneric]: #rawreply
1704
+ [LoggerGeneric]: #logger
1705
+ [RawBodyGeneric]: #rawbody
1706
+ [HTTPMethods]: #fastifyhttpmethods
1707
+ [RawServerBase]: #fastifyrawserverbase
1708
+ [RawServerDefault]: #fastifyrawserverdefault
1709
+ [FastifyRequest]: #fastifyfastifyrequestrawserver-rawrequest-requestgeneric
1710
+ [FastifyRequestGenericInterface]: #fastifyrequestgenericinterface
1711
+ [RawRequestDefaultExpression]: #fastifyrawrequestdefaultexpressionrawserver
1712
+ [FastifyReply]: #fastifyfastifyreplyrawserver-rawreply-contextconfig
1713
+ [RawReplyDefaultExpression]: #fastifyrawreplydefaultexpression
1714
+ [FastifyServerOptions]: #fastifyfastifyserveroptions-rawserver-logger
1715
+ [FastifyInstance]: #fastifyfastifyinstance
1716
+ [FastifyLoggerOptions]: #fastifyfastifyloggeroptions
1717
+ [ContextConfigGeneric]: #ContextConfigGeneric
1718
+ [FastifyPlugin]:
1719
+ #fastifyfastifypluginoptions-rawserver-rawrequest-requestgeneric
1720
+ [FastifyPluginCallback]: #fastifyfastifyplugincallbackoptions
1721
+ [FastifyPluginAsync]: #fastifyfastifypluginasyncoptions
1722
+ [FastifyPluginOptions]: #fastifyfastifypluginoptions
1723
+ [FastifyRegister]:
1724
+ #fastifyfastifyregisterrawserver-rawrequest-requestgenericplugin-fastifyplugin-opts-fastifyregisteroptions
1725
+ [FastifyRegisterOptions]: #fastifyfastifytregisteroptions
1726
+ [LogLevel]: #fastifyloglevel
1727
+ [FastifyError]: #fastifyfastifyerror
1728
+ [RouteOptions]:
1729
+ #fastifyrouteoptionsrawserver-rawrequest-rawreply-requestgeneric-contextconfig