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,287 @@
1
+ # V3 Migration Guide
2
+
3
+ This guide is intended to help with migration from Fastify v2 to v3.
4
+
5
+ Before beginning please ensure that any deprecation warnings from v2 are fixed.
6
+ All v2 deprecations have been removed and they will no longer work after
7
+ upgrading. ([#1750](https://github.com/fastify/fastify/pull/1750))
8
+
9
+ ## Breaking changes
10
+
11
+ ### Changed middleware support ([#2014](https://github.com/fastify/fastify/pull/2014))
12
+
13
+ From Fastify v3, middleware support does not come out-of-the-box with the
14
+ framework itself.
15
+
16
+ If you use Express middleware in your application, please install and register
17
+ the [`@fastify/express`](https://github.com/fastify/fastify-express) or
18
+ [`@fastify/middie`](https://github.com/fastify/middie) plugin before doing so.
19
+
20
+ **v2:**
21
+
22
+ ```js
23
+ // Using the Express `cors` middleware in Fastify v2.
24
+ fastify.use(require('cors')());
25
+ ```
26
+
27
+ **v3:**
28
+
29
+ ```js
30
+ // Using the Express `cors` middleware in Fastify v3.
31
+ await fastify.register(require('@fastify/express'));
32
+ fastify.use(require('cors')());
33
+ ```
34
+
35
+ ### Changed logging serialization ([#2017](https://github.com/fastify/fastify/pull/2017))
36
+
37
+ The logging [Serializers](../Reference/Logging.md) have been updated to now
38
+ Fastify [`Request`](../Reference/Request.md) and
39
+ [`Reply`](../Reference/Reply.md) objects instead of native ones.
40
+
41
+ Any custom serializers must be updated if they rely upon `request` or `reply`
42
+ properties that are present on the native objects but not the Fastify objects.
43
+
44
+ **v2:**
45
+
46
+ ```js
47
+ const fastify = require('fastify')({
48
+ logger: {
49
+ serializers: {
50
+ res(res) {
51
+ return {
52
+ statusCode: res.statusCode,
53
+ customProp: res.customProp
54
+ };
55
+ }
56
+ }
57
+ }
58
+ });
59
+ ```
60
+
61
+ **v3:**
62
+
63
+ ```js
64
+ const fastify = require('fastify')({
65
+ logger: {
66
+ serializers: {
67
+ res(reply) {
68
+ return {
69
+ statusCode: reply.statusCode, // No change required
70
+ customProp: reply.raw.customProp // Log custom property from res object
71
+ };
72
+ }
73
+ }
74
+ }
75
+ });
76
+ ```
77
+
78
+ ### Changed schema substitution ([#2023](https://github.com/fastify/fastify/pull/2023))
79
+
80
+ The non-standard `replace-way` shared schema support has been removed. This
81
+ feature has been replaced with JSON Schema specification compliant `$ref` based
82
+ substitution. To help understand this change read [Validation and Serialization
83
+ in Fastify
84
+ v3](https://dev.to/eomm/validation-and-serialization-in-fastify-v3-2e8l).
85
+
86
+ **v2:**
87
+
88
+ ```js
89
+ const schema = {
90
+ body: 'schemaId#'
91
+ };
92
+ fastify.route({ method, url, schema, handler });
93
+ ```
94
+
95
+ **v3:**
96
+
97
+ ```js
98
+ const schema = {
99
+ body: {
100
+ $ref: 'schemaId#'
101
+ }
102
+ };
103
+ fastify.route({ method, url, schema, handler });
104
+ ```
105
+
106
+ ### Changed schema validation options ([#2023](https://github.com/fastify/fastify/pull/2023))
107
+
108
+ The `setSchemaCompiler` and `setSchemaResolver` options have been replaced with
109
+ the `setValidatorCompiler` to enable future tooling improvements. To help
110
+ understand this change read [Validation and Serialization in Fastify
111
+ v3](https://dev.to/eomm/validation-and-serialization-in-fastify-v3-2e8l).
112
+
113
+ **v2:**
114
+
115
+ ```js
116
+ const fastify = Fastify();
117
+ const ajv = new AJV();
118
+ ajv.addSchema(schemaA);
119
+ ajv.addSchema(schemaB);
120
+
121
+ fastify.setSchemaCompiler(schema => ajv.compile(schema));
122
+ fastify.setSchemaResolver(ref => ajv.getSchema(ref).schema);
123
+ ```
124
+
125
+ **v3:**
126
+
127
+ ```js
128
+ const fastify = Fastify();
129
+ const ajv = new AJV();
130
+ ajv.addSchema(schemaA);
131
+ ajv.addSchema(schemaB);
132
+
133
+ fastify.setValidatorCompiler(({ schema, method, url, httpPart }) =>
134
+ ajv.compile(schema)
135
+ );
136
+ ```
137
+
138
+ ### Changed preParsing hook behavior ([#2286](https://github.com/fastify/fastify/pull/2286))
139
+
140
+ From Fastify v3, the behavior of the `preParsing` hook will change slightly
141
+ to support request payload manipulation.
142
+
143
+ The hook now takes an additional argument, `payload`, and therefore the new hook
144
+ signature is `fn(request, reply, payload, done)` or `async fn(request, reply,
145
+ payload)`.
146
+
147
+ The hook can optionally return a new stream via `done(null, stream)` or
148
+ returning the stream in case of async functions.
149
+
150
+ If the hook returns a new stream, it will be used instead of the original one in
151
+ subsequent hooks. A sample use case for this is handling compressed requests.
152
+
153
+ The new stream should add the `receivedEncodedLength` property to the stream
154
+ that should reflect the actual data size received from the client. For instance,
155
+ in a compressed request it should be the size of the compressed payload. This
156
+ property can (and should) be dynamically updated during `data` events.
157
+
158
+ The old syntax of Fastify v2 without payload is supported but it is deprecated.
159
+
160
+ ### Changed hooks behavior ([#2004](https://github.com/fastify/fastify/pull/2004))
161
+
162
+ From Fastify v3, the behavior of `onRoute` and `onRegister` hooks will change
163
+ slightly to support hook encapsulation.
164
+
165
+ - `onRoute` - The hook will be called asynchronously. The hook is now inherited
166
+ when registering a new plugin within the same encapsulation scope. Thus, this
167
+ hook should be registered _before_ registering any plugins.
168
+ - `onRegister` - Same as the onRoute hook. The only difference is that now the
169
+ very first call will no longer be the framework itself, but the first
170
+ registered plugin.
171
+
172
+ ### Changed Content Type Parser syntax ([#2286](https://github.com/fastify/fastify/pull/2286))
173
+
174
+ In Fastify v3 the content type parsers now have a single signature for parsers.
175
+
176
+ The new signatures are `fn(request, payload, done)` or `async fn(request,
177
+ payload)`. Note that `request` is now a Fastify request, not an
178
+ `IncomingMessage`. The payload is, by default, a stream. If the `parseAs` option
179
+ is used in `addContentTypeParser`, then `payload` reflects the option value
180
+ (string or buffer).
181
+
182
+ The old signatures `fn(req, [done])` or `fn(req, payload, [done])` (where `req`
183
+ is `IncomingMessage`) are still supported but are deprecated.
184
+
185
+ ### Changed TypeScript support
186
+
187
+ The type system was changed in Fastify version 3. The new type system introduces
188
+ generic constraining and defaulting, plus a new way to define schema types such
189
+ as a request body, querystring, and more!
190
+
191
+ **v2:**
192
+
193
+ ```ts
194
+ interface PingQuerystring {
195
+ foo?: number;
196
+ }
197
+
198
+ interface PingParams {
199
+ bar?: string;
200
+ }
201
+
202
+ interface PingHeaders {
203
+ a?: string;
204
+ }
205
+
206
+ interface PingBody {
207
+ baz?: string;
208
+ }
209
+
210
+ server.get<PingQuerystring, PingParams, PingHeaders, PingBody>(
211
+ '/ping/:bar',
212
+ opts,
213
+ (request, reply) => {
214
+ console.log(request.query); // This is of type `PingQuerystring`
215
+ console.log(request.params); // This is of type `PingParams`
216
+ console.log(request.headers); // This is of type `PingHeaders`
217
+ console.log(request.body); // This is of type `PingBody`
218
+ }
219
+ );
220
+ ```
221
+
222
+ **v3:**
223
+
224
+ ```ts
225
+ server.get<{
226
+ Querystring: PingQuerystring;
227
+ Params: PingParams;
228
+ Headers: PingHeaders;
229
+ Body: PingBody;
230
+ }>('/ping/:bar', opts, async (request, reply) => {
231
+ console.log(request.query); // This is of type `PingQuerystring`
232
+ console.log(request.params); // This is of type `PingParams`
233
+ console.log(request.headers); // This is of type `PingHeaders`
234
+ console.log(request.body); // This is of type `PingBody`
235
+ });
236
+ ```
237
+
238
+ ### Manage uncaught exception ([#2073](https://github.com/fastify/fastify/pull/2073))
239
+
240
+ In sync route handlers, if an error was thrown the server crashed by design
241
+ without calling the configured `.setErrorHandler()`. This has changed and now
242
+ all unexpected errors in sync and async routes are managed.
243
+
244
+ **v2:**
245
+
246
+ ```js
247
+ fastify.setErrorHandler((error, request, reply) => {
248
+ // this is NOT called
249
+ reply.send(error)
250
+ })
251
+ fastify.get('/', (request, reply) => {
252
+ const maybeAnArray = request.body.something ? [] : 'I am a string'
253
+ maybeAnArray.substr() // Thrown: [].substr is not a function and crash the server
254
+ })
255
+ ```
256
+
257
+ **v3:**
258
+
259
+ ```js
260
+ fastify.setErrorHandler((error, request, reply) => {
261
+ // this IS called
262
+ reply.send(error)
263
+ })
264
+ fastify.get('/', (request, reply) => {
265
+ const maybeAnArray = request.body.something ? [] : 'I am a string'
266
+ maybeAnArray.substr() // Thrown: [].substr is not a function, but it is handled
267
+ })
268
+ ```
269
+
270
+ ## Further additions and improvements
271
+
272
+ - Hooks now have consistent context regardless of how they are registered
273
+ ([#2005](https://github.com/fastify/fastify/pull/2005))
274
+ - Deprecated `request.req` and `reply.res` for
275
+ [`request.raw`](../Reference/Request.md) and
276
+ [`reply.raw`](../Reference/Reply.md)
277
+ ([#2008](https://github.com/fastify/fastify/pull/2008))
278
+ - Removed `modifyCoreObjects` option
279
+ ([#2015](https://github.com/fastify/fastify/pull/2015))
280
+ - Added [`connectionTimeout`](../Reference/Server.md#factory-connection-timeout)
281
+ option ([#2086](https://github.com/fastify/fastify/pull/2086))
282
+ - Added [`keepAliveTimeout`](../Reference/Server.md#factory-keep-alive-timeout)
283
+ option ([#2086](https://github.com/fastify/fastify/pull/2086))
284
+ - Added async-await support for [plugins](../Reference/Plugins.md#async-await)
285
+ ([#2093](https://github.com/fastify/fastify/pull/2093))
286
+ - Added the feature to throw object as error
287
+ ([#2134](https://github.com/fastify/fastify/pull/2134))
@@ -0,0 +1,267 @@
1
+ # V4 Migration Guide
2
+
3
+ This guide is intended to help with migration from Fastify v3 to v4.
4
+
5
+ Before migrating to v4, please ensure that you have fixed all deprecation
6
+ warnings from v3. All v3 deprecations have been removed and they will no longer
7
+ work after upgrading.
8
+
9
+ ## Codemods
10
+ ### Fastify v4 Codemods
11
+
12
+ To help with the upgrade, we’ve worked with the team at
13
+ [Codemod](https://github.com/codemod-com/codemod) to
14
+ publish codemods that will automatically update your code to many of
15
+ the new APIs and patterns in Fastify v4.
16
+
17
+
18
+ ```bash
19
+ npx codemod@latest fastify/4/migration-recipe
20
+ ```
21
+ This applies the following codemods:
22
+
23
+ - fastify/4/remove-app-use
24
+ - fastify/4/reply-raw-access
25
+ - fastify/4/wrap-routes-plugin
26
+ - fastify/4/await-register-calls
27
+
28
+ For information on the migration recipe, see
29
+ https://app.codemod.com/registry/fastify/4/migration-recipe.
30
+
31
+
32
+ ## Breaking Changes
33
+
34
+ ### Error handling composition ([#3261](https://github.com/fastify/fastify/pull/3261))
35
+
36
+ When an error is thrown in an async error handler function, the upper-level
37
+ error handler is executed if set. If there is no upper-level error handler,
38
+ the default will be executed as it was previously:
39
+
40
+ ```js
41
+ import Fastify from 'fastify'
42
+
43
+ const fastify = Fastify()
44
+
45
+ fastify.register(async fastify => {
46
+ fastify.setErrorHandler(async err => {
47
+ console.log(err.message) // 'kaboom'
48
+ throw new Error('caught')
49
+ })
50
+
51
+ fastify.get('/encapsulated', async () => {
52
+ throw new Error('kaboom')
53
+ })
54
+ })
55
+
56
+ fastify.setErrorHandler(async err => {
57
+ console.log(err.message) // 'caught'
58
+ throw new Error('wrapped')
59
+ })
60
+
61
+ const res = await fastify.inject('/encapsulated')
62
+ console.log(res.json().message) // 'wrapped'
63
+ ```
64
+
65
+ >The root error handler is Fastify’s generic error handler.
66
+ >This error handler will use the headers and status code in the Error object,
67
+ >if they exist. **The headers and status code will not be automatically set if
68
+ >a custom error handler is provided**.
69
+
70
+ ### Removed `app.use()` ([#3506](https://github.com/fastify/fastify/pull/3506))
71
+
72
+ With v4 of Fastify, `app.use()` has been removed and the use of middleware is
73
+ no longer supported.
74
+
75
+ If you need to use middleware, use
76
+ [`@fastify/middie`](https://github.com/fastify/middie) or
77
+ [`@fastify/express`](https://github.com/fastify/fastify-express), which will
78
+ continue to be maintained.
79
+ However, it is strongly recommended that you migrate to Fastify's [hooks](../Reference/Hooks.md).
80
+
81
+ > ℹ️ Note:
82
+ > Codemod remove `app.use()` with:
83
+ > ```bash
84
+ > npx codemod@latest fastify/4/remove-app-use
85
+ > ```
86
+
87
+ ### `reply.res` moved to `reply.raw`
88
+
89
+ If you previously used the `reply.res` attribute to access the underlying Request
90
+ object you will now need to use `reply.raw`.
91
+
92
+ > ℹ️ Note:
93
+ > Codemod `reply.res` to `reply.raw` with:
94
+ > ```bash
95
+ > npx codemod@latest fastify/4/reply-raw-access
96
+ > ```
97
+
98
+ ### Need to `return reply` to signal a "fork" of the promise chain
99
+
100
+ In some situations, like when a response is sent asynchronously or when you are
101
+ not explicitly returning a response, you will now need to return the `reply`
102
+ argument from your router handler.
103
+
104
+ ### `exposeHeadRoutes` true by default
105
+
106
+ Starting with v4, every `GET` route will create a sibling `HEAD` route.
107
+ You can revert this behavior by setting `exposeHeadRoutes: false` in the server
108
+ options.
109
+
110
+ ### Synchronous route definitions ([#2954](https://github.com/fastify/fastify/pull/2954))
111
+
112
+ To improve error reporting in route definitions, route registration is now synchronous.
113
+ As a result, if you specify an `onRoute` hook in a plugin you should now either:
114
+ * wrap your routes in a plugin (recommended)
115
+
116
+ For example, refactor this:
117
+ ```js
118
+ fastify.register((instance, opts, done) => {
119
+ instance.addHook('onRoute', (routeOptions) => {
120
+ const { path, method } = routeOptions;
121
+ console.log({ path, method });
122
+ done();
123
+ });
124
+ });
125
+
126
+ fastify.get('/', (request, reply) => { reply.send('hello') });
127
+ ```
128
+
129
+ Into this:
130
+ ```js
131
+ fastify.register((instance, opts, done) => {
132
+ instance.addHook('onRoute', (routeOptions) => {
133
+ const { path, method } = routeOptions;
134
+ console.log({ path, method });
135
+ done();
136
+ });
137
+ });
138
+
139
+ fastify.register((instance, opts, done) => {
140
+ instance.get('/', (request, reply) => { reply.send('hello') });
141
+ done();
142
+ });
143
+ ```
144
+
145
+ > ℹ️ Note:
146
+ > Codemod synchronous route definitions with:
147
+ > ```bash
148
+ > npx codemod@latest fastify/4/wrap-routes-plugin
149
+ > ```
150
+
151
+ * use `await register(...)`
152
+
153
+ For example, refactor this:
154
+ ```js
155
+ fastify.register((instance, opts, done) => {
156
+ instance.addHook('onRoute', (routeOptions) => {
157
+ const { path, method } = routeOptions;
158
+ console.log({ path, method });
159
+ });
160
+ done();
161
+ });
162
+ ```
163
+
164
+ Into this:
165
+ ```js
166
+ await fastify.register((instance, opts, done) => {
167
+ instance.addHook('onRoute', (routeOptions) => {
168
+ const { path, method } = routeOptions;
169
+ console.log({ path, method });
170
+ });
171
+ done();
172
+ });
173
+ ```
174
+
175
+ > ℹ️ Note:
176
+ > Codemod 'await register(...)' with:
177
+ > ```bash
178
+ > npx codemod@latest fastify/4/await-register-calls
179
+ > ```
180
+
181
+
182
+ ### Optional URL parameters
183
+
184
+ If you've already used any implicitly optional parameters, you'll get a 404
185
+ error when trying to access the route. You will now need to declare the
186
+ optional parameters explicitly.
187
+
188
+ For example, if you have the same route for listing and showing a post,
189
+ refactor this:
190
+ ```js
191
+ fastify.get('/posts/:id', (request, reply) => {
192
+ const { id } = request.params;
193
+ });
194
+ ```
195
+
196
+ Into this:
197
+ ```js
198
+ fastify.get('/posts/:id?', (request, reply) => {
199
+ const { id } = request.params;
200
+ });
201
+ ```
202
+
203
+ ## Non-Breaking Changes
204
+
205
+ ### Deprecation of variadic `.listen()` signature
206
+
207
+ The [variadic signature](https://en.wikipedia.org/wiki/Variadic_function) of the
208
+ `fastify.listen()` method is now deprecated.
209
+
210
+ Before this release, the following invocations of this method were valid:
211
+
212
+ - `fastify.listen(8000)`
213
+ - `fastify.listen(8000, ‘127.0.0.1’)`
214
+ - `fastify.listen(8000, ‘127.0.0.1’, 511)`
215
+ - `fastify.listen(8000, (err) => { if (err) throw err })`
216
+ - `fastify.listen({ port: 8000 }, (err) => { if (err) throw err })`
217
+
218
+ With Fastify v4, only the following invocations are valid:
219
+
220
+ - `fastify.listen()`
221
+ - `fastify.listen({ port: 8000 })`
222
+ - `fastify.listen({ port: 8000 }, (err) => { if (err) throw err })`
223
+
224
+ ### Change of schema for multiple types
225
+
226
+ Ajv has been upgraded to v8 in Fastify v4, meaning "type" keywords with multiple
227
+ types other than "null"
228
+ [are now prohibited](https://ajv.js.org/strict-mode.html#strict-types).
229
+
230
+ You may encounter a console warning such as:
231
+ ```sh
232
+ strict mode: use allowUnionTypes to allow union type keyword at "#/properties/image" (strictTypes)
233
+ ```
234
+
235
+ As such, schemas like below will need to be changed from:
236
+ ```js
237
+ {
238
+ type: 'object',
239
+ properties: {
240
+ api_key: { type: 'string' },
241
+ image: { type: ['object', 'array'] }
242
+ }
243
+ }
244
+ ```
245
+
246
+ Into:
247
+ ```js
248
+ {
249
+ type: 'object',
250
+ properties: {
251
+ api_key: { type: 'string' },
252
+ image: {
253
+ anyOf: [
254
+ { type: 'array' },
255
+ { type: 'object' }
256
+ ]
257
+ }
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### Add `reply.trailers` methods ([#3794](https://github.com/fastify/fastify/pull/3794))
263
+
264
+ Fastify now supports the [HTTP Trailer] response headers.
265
+
266
+
267
+ [HTTP Trailer]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer