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,245 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## Plugins
4
+ Fastify can be extended with plugins, which can be a set of routes, a server
5
+ [decorator](./Decorators.md), or other functionality. Use the `register` API to
6
+ add one or more plugins.
7
+
8
+ By default, `register` creates a *new scope*, meaning changes to the Fastify
9
+ instance (via `decorate`) will not affect the current context ancestors, only
10
+ its descendants. This feature enables plugin *encapsulation* and *inheritance*,
11
+ creating a *directed acyclic graph* (DAG) and avoiding cross-dependency issues.
12
+
13
+ The [Getting Started](../Guides/Getting-Started.md#your-first-plugin) guide
14
+ includes an example of using this API:
15
+ ```js
16
+ fastify.register(plugin, [options])
17
+ ```
18
+
19
+ ### Plugin Options
20
+ <a id="plugin-options"></a>
21
+
22
+ The optional `options` parameter for `fastify.register` supports a predefined
23
+ set of options that Fastify itself will use, except when the plugin has been
24
+ wrapped with [fastify-plugin](https://github.com/fastify/fastify-plugin). This
25
+ options object will also be passed to the plugin upon invocation, regardless of
26
+ whether or not the plugin has been wrapped. The currently supported list of
27
+ Fastify specific options is:
28
+
29
+ + [`logLevel`](./Routes.md#custom-log-level)
30
+ + [`logSerializers`](./Routes.md#custom-log-serializer)
31
+ + [`prefix`](#route-prefixing-option)
32
+
33
+ These options will be ignored when used with fastify-plugin.
34
+
35
+ To avoid collisions, a plugin should consider namespacing its options. For
36
+ example, a plugin `foo` might be registered like so:
37
+
38
+ ```js
39
+ fastify.register(require('fastify-foo'), {
40
+ prefix: '/foo',
41
+ foo: {
42
+ fooOption1: 'value',
43
+ fooOption2: 'value'
44
+ }
45
+ })
46
+ ```
47
+
48
+ If collisions are not a concern, the plugin may accept the options object as-is:
49
+
50
+ ```js
51
+ fastify.register(require('fastify-foo'), {
52
+ prefix: '/foo',
53
+ fooOption1: 'value',
54
+ fooOption2: 'value'
55
+ })
56
+ ```
57
+
58
+ The `options` parameter can also be a `Function` evaluated at plugin registration,
59
+ providing access to the Fastify instance via the first argument:
60
+
61
+ ```js
62
+ const fp = require('fastify-plugin')
63
+
64
+ fastify.register(fp((fastify, opts, done) => {
65
+ fastify.decorate('foo_bar', { hello: 'world' })
66
+
67
+ done()
68
+ }))
69
+
70
+ // The opts argument of fastify-foo will be { hello: 'world' }
71
+ fastify.register(require('fastify-foo'), parent => parent.foo_bar)
72
+ ```
73
+
74
+ The Fastify instance passed to the function is the latest state of the **external
75
+ Fastify instance** the plugin was declared on, allowing access to variables
76
+ injected via [`decorate`](./Decorators.md) by preceding plugins according to the
77
+ **order of registration**. This is useful if a plugin depends on changes made to
78
+ the Fastify instance by a preceding plugin, such as utilizing an existing database
79
+ connection.
80
+
81
+ Keep in mind that the Fastify instance passed to the function is the same as the
82
+ one passed into the plugin, a copy of the external Fastify instance rather than
83
+ a reference. Any usage of the instance will behave the same as it would if called
84
+ within the plugin's function. For example, if `decorate` is called, the decorated
85
+ variables will be available within the plugin's function unless it was wrapped
86
+ with [`fastify-plugin`](https://github.com/fastify/fastify-plugin).
87
+
88
+ #### Route Prefixing option
89
+ <a id="route-prefixing-option"></a>
90
+
91
+ If an option with the key `prefix` and a `string` value is passed, Fastify will
92
+ use it to prefix all the routes inside the register. For more info, check
93
+ [here](./Routes.md#route-prefixing).
94
+
95
+ Be aware that if routes are wrapped with
96
+ [`fastify-plugin`](https://github.com/fastify/fastify-plugin), this option will
97
+ not work (see the [workaround](./Routes.md#fastify-plugin)).
98
+
99
+ #### Error handling
100
+ <a id="error-handling"></a>
101
+
102
+ Error handling is done by [avvio](https://github.com/mcollina/avvio#error-handling).
103
+
104
+ As a general rule, handle errors in the next `after` or `ready` block, otherwise
105
+ they will be caught inside the `listen` callback.
106
+
107
+ ```js
108
+ fastify.register(require('my-plugin'))
109
+
110
+ // `after` will be executed once
111
+ // the previous declared `register` has finished
112
+ fastify.after(err => console.log(err))
113
+
114
+ // `ready` will be executed once all the registers declared
115
+ // have finished their execution
116
+ fastify.ready(err => console.log(err))
117
+
118
+ // `listen` is a special ready,
119
+ // so it behaves in the same way
120
+ fastify.listen({ port: 3000 }, (err, address) => {
121
+ if (err) console.log(err)
122
+ })
123
+ ```
124
+
125
+ ### async/await
126
+ <a id="async-await"></a>
127
+
128
+ *async/await* is supported by `after`, `ready`, and `listen`, as well as
129
+ `fastify` being a Thenable.
130
+
131
+ ```js
132
+ await fastify.register(require('my-plugin'))
133
+
134
+ await fastify.after()
135
+
136
+ await fastify.ready()
137
+
138
+ await fastify.listen({ port: 3000 })
139
+ ```
140
+ Using `await` when registering a plugin loads the plugin and its dependencies,
141
+ "finalizing" the encapsulation process. Any mutations to the plugin after it and
142
+ its dependencies have been loaded will not be reflected in the parent instance.
143
+
144
+ #### ESM support
145
+ <a id="esm-support"></a>
146
+
147
+ ESM is supported from [Node.js `v13.3.0`](https://nodejs.org/api/esm.html)
148
+ and above.
149
+
150
+ ```js
151
+ // main.mjs
152
+ import Fastify from 'fastify'
153
+ const fastify = Fastify()
154
+
155
+ fastify.register(import('./plugin.mjs'))
156
+
157
+ fastify.listen({ port: 3000 }, console.log)
158
+
159
+
160
+ // plugin.mjs
161
+ async function plugin (fastify, opts) {
162
+ fastify.get('/', async (req, reply) => {
163
+ return { hello: 'world' }
164
+ })
165
+ }
166
+
167
+ export default plugin
168
+ ```
169
+
170
+ ### Create a plugin
171
+ <a id="create-plugin"></a>
172
+
173
+ Creating a plugin is easy. Create a function that takes three parameters: the
174
+ `fastify` instance, an `options` object, and the `done` callback. Alternatively,
175
+ use an `async` function and omit the `done` callback.
176
+
177
+ Example:
178
+ ```js
179
+ module.exports = function callbackPlugin (fastify, opts, done) {
180
+ fastify.decorate('utility', function () {})
181
+
182
+ fastify.get('/', handler)
183
+
184
+ done()
185
+ }
186
+
187
+ // Or using async
188
+ module.exports = async function asyncPlugin (fastify, opts) {
189
+ fastify.decorate('utility', function () {})
190
+
191
+ fastify.get('/', handler)
192
+ }
193
+ ```
194
+
195
+ `register` can also be used inside another `register`:
196
+ ```js
197
+ module.exports = function (fastify, opts, done) {
198
+ fastify.decorate('utility', function () {})
199
+
200
+ fastify.get('/', handler)
201
+
202
+ fastify.register(require('./other-plugin'))
203
+
204
+ done()
205
+ }
206
+ ```
207
+
208
+ Remember, `register` always creates a new Fastify scope. If this is not needed,
209
+ read the following section.
210
+
211
+ ### Handle the scope
212
+ <a id="handle-scope"></a>
213
+
214
+ If `register` is used only to extend server functionality with
215
+ [`decorate`](./Decorators.md), tell Fastify not to create a new scope. Otherwise,
216
+ changes will not be accessible in the upper scope.
217
+
218
+ There are two ways to avoid creating a new context:
219
+ - Use the [`fastify-plugin`](https://github.com/fastify/fastify-plugin) module
220
+ - Use the `'skip-override'` hidden property
221
+
222
+ Using the `fastify-plugin` module is recommended, as it solves this problem and
223
+ allows passing a version range of Fastify that the plugin will support:
224
+ ```js
225
+ const fp = require('fastify-plugin')
226
+
227
+ module.exports = fp(function (fastify, opts, done) {
228
+ fastify.decorate('utility', function () {})
229
+ done()
230
+ }, '0.x')
231
+ ```
232
+ Check the [`fastify-plugin`](https://github.com/fastify/fastify-plugin)
233
+ documentation to learn more about how to use this module.
234
+
235
+ If not using `fastify-plugin`, the `'skip-override'` hidden property can be used,
236
+ but it is not recommended. Future Fastify API changes will be your responsibility
237
+ to update, whilst `fastify-plugin` ensures backward compatibility.
238
+ ```js
239
+ function yourPlugin (fastify, opts, done) {
240
+ fastify.decorate('utility', function () {})
241
+ done()
242
+ }
243
+ yourPlugin[Symbol.for('skip-override')] = true
244
+ module.exports = yourPlugin
245
+ ```
@@ -0,0 +1,73 @@
1
+ # Technical Principles
2
+
3
+ Every decision in the Fastify framework and its official plugins is guided by
4
+ the following technical principles:
5
+
6
+ 1. “Zero” overhead in production
7
+ 2. “Good” developer experience
8
+ 3. Works great for small & big projects alike
9
+ 4. Easy to migrate to microservices (or even serverless) and back
10
+ 5. Security & data validation
11
+ 6. If something could be a plugin, it likely should be
12
+ 7. Easily testable
13
+ 8. Do not monkeypatch core
14
+ 9. Semantic versioning & Long Term Support
15
+ 10. Specification adherence
16
+
17
+ ## "Zero" Overhead in Production
18
+
19
+ Fastify aims to implement features with minimal overhead. This is achieved by
20
+ using fast algorithms, data structures, and JavaScript-specific features.
21
+
22
+ Since JavaScript does not offer zero-overhead data structures, this principle
23
+ can conflict with providing a great developer experience and additional features,
24
+ as these usually incur some overhead.
25
+
26
+ ## "Good" Developer Experience
27
+
28
+ Fastify aims to provide the best developer experience at its performance point.
29
+ It offers a great out-of-the-box experience that is flexible enough to adapt to
30
+ various situations.
31
+
32
+ For example, binary addons are forbidden because most JavaScript developers do
33
+ not have access to a compiler.
34
+
35
+ ## Works great for small and big projects alike
36
+
37
+ Most applications start small and become more complex over time. Fastify aims to
38
+ grow with this complexity, providing advanced features to structure codebases.
39
+
40
+ ## Easy to migrate to microservices (or even serverless) and back
41
+
42
+ Route deployment should not matter. The framework should "just work".
43
+
44
+ ## Security and Data Validation
45
+
46
+ A web framework is the first point of contact with untrusted data and must act
47
+ as the first line of defense for the system.
48
+
49
+ ## If something could be a plugin, it likely should
50
+
51
+ Recognizing the infinite use cases for an HTTP framework, catering to all in a
52
+ single module would make the codebase unmaintainable. Therefore, hooks and
53
+ options are provided to customize the framework as needed.
54
+
55
+ ## Easily testable
56
+
57
+ Testing Fastify applications should be a first-class concern.
58
+
59
+ ## Do not monkeypatch core
60
+
61
+ Monkeypatching Node.js APIs or installing globals that alter the runtime makes
62
+ building modular applications harder and limits Fastify's use cases. Other
63
+ frameworks do this; Fastify does not.
64
+
65
+ ## Semantic Versioning and Long Term Support
66
+
67
+ A clear [Long Term Support strategy is provided](./LTS.md) to inform developers
68
+ when to upgrade.
69
+
70
+ ## Specification adherence
71
+
72
+ In doubt, we chose the strict behavior as defined by the relevant
73
+ Specifications.