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,378 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## Recommendations
4
+
5
+ This document contains a set of recommendations when using Fastify.
6
+
7
+ - [Use A Reverse Proxy](#use-a-reverse-proxy)
8
+ - [HAProxy](#haproxy)
9
+ - [Nginx](#nginx)
10
+ - [Common Causes Of Performance Degradation](#common-causes-of-performance-degradation)
11
+ - [Kubernetes](#kubernetes)
12
+ - [Capacity Planning For Production](#capacity)
13
+ - [Running Multiple Instances](#multiple)
14
+
15
+ ## Use A Reverse Proxy
16
+ <a id="reverseproxy"></a>
17
+
18
+ Node.js is an early adopter of frameworks shipping with an easy-to-use web
19
+ server within the standard library. Previously, with languages like PHP or
20
+ Python, one would need either a web server with specific support for the
21
+ language or the ability to set up some sort of [CGI gateway][cgi] that works
22
+ with the language. With Node.js, one can write an application that _directly_
23
+ handles HTTP requests. As a result, the temptation is to write applications that
24
+ handle requests for multiple domains, listen on multiple ports (i.e. HTTP _and_
25
+ HTTPS), and then expose these applications directly to the Internet to handle
26
+ requests.
27
+
28
+ The Fastify team **strongly** considers this to be an anti-pattern and extremely
29
+ bad practice:
30
+
31
+ 1. It adds unnecessary complexity to the application by diluting its focus.
32
+ 2. It prevents [horizontal scalability][scale-horiz].
33
+
34
+ See [Why should I use a Reverse Proxy if Node.js is Production Ready?][why-use]
35
+ for a more thorough discussion of why one should opt to use a reverse proxy.
36
+
37
+ For a concrete example, consider the situation where:
38
+
39
+ 1. The app needs multiple instances to handle load.
40
+ 1. The app needs TLS termination.
41
+ 1. The app needs to redirect HTTP requests to HTTPS.
42
+ 1. The app needs to serve multiple domains.
43
+ 1. The app needs to serve static resources, e.g. jpeg files.
44
+
45
+ There are many reverse proxy solutions available, and your environment may
46
+ dictate the solution to use, e.g. AWS or GCP. Given the above, we could use
47
+ [HAProxy][haproxy] or [Nginx][nginx] to solve these requirements:
48
+
49
+ ### HAProxy
50
+
51
+ ```conf
52
+ # The global section defines base HAProxy (engine) instance configuration.
53
+ global
54
+ log /dev/log syslog
55
+ maxconn 4096
56
+ chroot /var/lib/haproxy
57
+ user haproxy
58
+ group haproxy
59
+
60
+ # Set some baseline TLS options.
61
+ tune.ssl.default-dh-param 2048
62
+ ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11
63
+ ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
64
+ ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11
65
+ ssl-default-server-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
66
+
67
+ # Each defaults section defines options that will apply to each subsequent
68
+ # subsection until another defaults section is encountered.
69
+ defaults
70
+ log global
71
+ mode http
72
+ option httplog
73
+ option dontlognull
74
+ retries 3
75
+ option redispatch
76
+ # The following option makes haproxy close connections to backend servers
77
+ # instead of keeping them open. This can alleviate unexpected connection
78
+ # reset errors in the Node process.
79
+ option http-server-close
80
+ maxconn 2000
81
+ timeout connect 5000
82
+ timeout client 50000
83
+ timeout server 50000
84
+
85
+ # Enable content compression for specific content types.
86
+ compression algo gzip
87
+ compression type text/html text/plain text/css application/javascript
88
+
89
+ # A "frontend" section defines a public listener, i.e. an "http server"
90
+ # as far as clients are concerned.
91
+ frontend proxy
92
+ # The IP address here would be the _public_ IP address of the server.
93
+ # Here, we use a private address as an example.
94
+ bind 10.0.0.10:80
95
+ # This redirect rule will redirect all traffic that is not TLS traffic
96
+ # to the same incoming request URL on the HTTPS port.
97
+ redirect scheme https code 308 if !{ ssl_fc }
98
+ # Technically this use_backend directive is useless since we are simply
99
+ # redirecting all traffic to this frontend to the HTTPS frontend. It is
100
+ # merely included here for completeness sake.
101
+ use_backend default-server
102
+
103
+ # This frontend defines our primary, TLS only, listener. It is here where
104
+ # we will define the TLS certificates to expose and how to direct incoming
105
+ # requests.
106
+ frontend proxy-ssl
107
+ # The `/etc/haproxy/certs` directory in this example contains a set of
108
+ # certificate PEM files that are named for the domains the certificates are
109
+ # issued for. When HAProxy starts, it will read this directory, load all of
110
+ # the certificates it finds here, and use SNI matching to apply the correct
111
+ # certificate to the connection.
112
+ bind 10.0.0.10:443 ssl crt /etc/haproxy/certs
113
+
114
+ # Here we define rule pairs to handle static resources. Any incoming request
115
+ # that has a path starting with `/static`, e.g.
116
+ # `https://one.fastify.example/static/foo.jpeg`, will be redirected to the
117
+ # static resources server.
118
+ acl is_static path -i -m beg /static
119
+ use_backend static-backend if is_static
120
+
121
+ # Here we define rule pairs to direct requests to appropriate Node.js
122
+ # servers based on the requested domain. The `acl` line is used to match
123
+ # the incoming hostname and define a boolean indicating if it is a match.
124
+ # The `use_backend` line is used to direct the traffic if the boolean is
125
+ # true.
126
+ acl example1 hdr_sub(Host) one.fastify.example
127
+ use_backend example1-backend if example1
128
+
129
+ acl example2 hdr_sub(Host) two.fastify.example
130
+ use_backend example2-backend if example2
131
+
132
+ # Finally, we have a fallback redirect if none of the requested hosts
133
+ # match the above rules.
134
+ default_backend default-server
135
+
136
+ # A "backend" is used to tell HAProxy where to request information for the
137
+ # proxied request. These sections are where we will define where our Node.js
138
+ # apps live and any other servers for things like static assets.
139
+ backend default-server
140
+ # In this example we are defaulting unmatched domain requests to a single
141
+ # backend server for all requests. Notice that the backend server does not
142
+ # have to be serving TLS requests. This is called "TLS termination": the TLS
143
+ # connection is "terminated" at the reverse proxy.
144
+ # It is possible to also proxy to backend servers that are themselves serving
145
+ # requests over TLS, but that is outside the scope of this example.
146
+ server server1 10.10.10.2:80
147
+
148
+ # This backend configuration will serve requests for `https://one.fastify.example`
149
+ # by proxying requests to three backend servers in a round-robin manner.
150
+ backend example1-backend
151
+ server example1-1 10.10.11.2:80
152
+ server example1-2 10.10.11.2:80
153
+ server example2-2 10.10.11.3:80
154
+
155
+ # This one serves requests for `https://two.fastify.example`
156
+ backend example2-backend
157
+ server example2-1 10.10.12.2:80
158
+ server example2-2 10.10.12.2:80
159
+ server example2-3 10.10.12.3:80
160
+
161
+ # This backend handles the static resources requests.
162
+ backend static-backend
163
+ server static-server1 10.10.9.2:80
164
+ ```
165
+
166
+ [cgi]: https://en.wikipedia.org/wiki/Common_Gateway_Interface
167
+ [scale-horiz]: https://en.wikipedia.org/wiki/Scalability#Horizontal
168
+ [why-use]: https://web.archive.org/web/20190821102906/https://medium.com/intrinsic/why-should-i-use-a-reverse-proxy-if-node-js-is-production-ready-5a079408b2ca
169
+ [haproxy]: https://www.haproxy.org/
170
+
171
+ ### Nginx
172
+
173
+ ```nginx
174
+ # This upstream block groups 3 servers into one named backend fastify_app
175
+ # with 2 primary servers distributed via round-robin
176
+ # and one backup which is used when the first 2 are not reachable
177
+ # This also assumes your fastify servers are listening on port 80.
178
+ # more info: https://nginx.org/en/docs/http/ngx_http_upstream_module.html
179
+ upstream fastify_app {
180
+ server 10.10.11.1:80;
181
+ server 10.10.11.2:80;
182
+ server 10.10.11.3:80 backup;
183
+ }
184
+
185
+ # This server block asks NGINX to respond with a redirect when
186
+ # an incoming request from port 80 (typically plain HTTP), to
187
+ # the same request URL but with HTTPS as protocol.
188
+ # This block is optional, and usually used if you are handling
189
+ # SSL termination in NGINX, like in the example here.
190
+ server {
191
+ # default server is a special parameter to ask NGINX
192
+ # to set this server block to the default for this address/port
193
+ # which in this case is any address and port 80
194
+ listen 80 default_server;
195
+ listen [::]:80 default_server;
196
+
197
+ # With a server_name directive you can also ask NGINX to
198
+ # use this server block only with matching server name(s)
199
+ # listen 80;
200
+ # listen [::]:80;
201
+ # server_name example.tld;
202
+
203
+ # This matches all paths from the request and responds with
204
+ # the redirect mentioned above.
205
+ location / {
206
+ return 301 https://$host$request_uri;
207
+ }
208
+ }
209
+
210
+ # This server block asks NGINX to respond to requests from
211
+ # port 443 with SSL enabled and accept HTTP/2 connections.
212
+ # This is where the request is then proxied to the fastify_app
213
+ # server group via port 3000.
214
+ server {
215
+ # This listen directive asks NGINX to accept requests
216
+ # coming to any address, port 443, with SSL.
217
+ listen 443 ssl default_server;
218
+ listen [::]:443 ssl default_server;
219
+
220
+ # With a server_name directive you can also ask NGINX to
221
+ # use this server block only with matching server name(s)
222
+ # listen 443 ssl;
223
+ # listen [::]:443 ssl;
224
+ # server_name example.tld;
225
+
226
+ # Enable HTTP/2 support
227
+ http2 on;
228
+
229
+ # Your SSL/TLS certificate (chain) and secret key in the PEM format
230
+ ssl_certificate /path/to/fullchain.pem;
231
+ ssl_certificate_key /path/to/private.pem;
232
+
233
+ # A generic best practice baseline for based
234
+ # on https://ssl-config.mozilla.org/
235
+ ssl_session_timeout 1d;
236
+ ssl_session_cache shared:FastifyApp:10m;
237
+ ssl_session_tickets off;
238
+
239
+ # This tells NGINX to only accept TLS 1.3, which should be fine
240
+ # with most modern browsers including IE 11 with certain updates.
241
+ # If you want to support older browsers you might need to add
242
+ # additional fallback protocols.
243
+ ssl_protocols TLSv1.3;
244
+ ssl_prefer_server_ciphers off;
245
+
246
+ # This adds a header that tells browsers to only ever use HTTPS
247
+ # with this server.
248
+ add_header Strict-Transport-Security "max-age=63072000" always;
249
+
250
+ # The following directives are only necessary if you want to
251
+ # enable OCSP Stapling.
252
+ ssl_stapling on;
253
+ ssl_stapling_verify on;
254
+ ssl_trusted_certificate /path/to/chain.pem;
255
+
256
+ # Custom nameserver to resolve upstream server names
257
+ # resolver 127.0.0.1;
258
+
259
+ # This section matches all paths and proxies it to the backend server
260
+ # group specified above. Note the additional headers that forward
261
+ # information about the original request. You might want to set
262
+ # trustProxy to the address of your NGINX server so the X-Forwarded
263
+ # fields are used by fastify.
264
+ location / {
265
+ # more info: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
266
+ proxy_http_version 1.1;
267
+ proxy_cache_bypass $http_upgrade;
268
+ proxy_set_header Upgrade $http_upgrade;
269
+ proxy_set_header Connection 'upgrade';
270
+ proxy_set_header Host $host;
271
+ proxy_set_header X-Real-IP $remote_addr;
272
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
273
+ proxy_set_header X-Forwarded-Proto $scheme;
274
+
275
+ # This is the directive that proxies requests to the specified server.
276
+ # If you are using an upstream group, then you do not need to specify a port.
277
+ # If you are directly proxying to a server e.g.
278
+ # proxy_pass http://127.0.0.1:3000 then specify a port.
279
+ proxy_pass http://fastify_app;
280
+ }
281
+ }
282
+ ```
283
+
284
+ [nginx]: https://nginx.org/
285
+
286
+ ## Common Causes Of Performance Degradation
287
+
288
+ These patterns can increase latency or reduce throughput in production:
289
+
290
+ - Prefer static or simple parametric routes on hot paths. RegExp routes are
291
+ expensive, and routes with many parameters can also hurt router performance.
292
+ See [Routes - Url building](../Reference/Routes.md#url-building).
293
+ - Use route constraints carefully. Version constraints can degrade router
294
+ performance, and asynchronous custom constraints should be treated as a last
295
+ resort. See [Routes - Constraints](../Reference/Routes.md#constraints).
296
+ - Prefer Fastify plugins/hooks over generic middleware when possible. Fastify's
297
+ middleware adapters work, but native integrations are typically better for
298
+ performance-sensitive paths. See [Middleware](../Reference/Middleware.md).
299
+ - Define response schemas to speed up JSON serialization. See
300
+ [Getting Started - Serialize your data](./Getting-Started.md#serialize-data).
301
+ - Keep Ajv `allErrors` disabled by default. Enable it only when detailed
302
+ validation feedback is needed (for example, form-heavy APIs), and avoid it
303
+ on latency-sensitive endpoints. When `allErrors: true` is enabled, validation
304
+ can do more work per request and make denial-of-service attacks easier on
305
+ untrusted inputs.
306
+ See also:
307
+ - [Validation and Serialization - Validator Compiler](../Reference/Validation-and-Serialization.md#schema-validator)
308
+ - [Ajv Security Risks of Trusted Schemas](https://ajv.js.org/security.html#security-risks-of-trusted-schemas).
309
+
310
+ ## Kubernetes
311
+ <a id="kubernetes"></a>
312
+
313
+ The `readinessProbe` uses ([by
314
+ default](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes))
315
+ the pod IP as the hostname. Fastify listens on `127.0.0.1` by default. The probe
316
+ will not be able to reach the application in this case. To make it work,
317
+ the application must listen on `0.0.0.0` or specify a custom hostname in
318
+ the `readinessProbe.httpGet` spec, as per the following example:
319
+
320
+ ```yaml
321
+ readinessProbe:
322
+ httpGet:
323
+ path: /health
324
+ port: 4000
325
+ initialDelaySeconds: 30
326
+ periodSeconds: 30
327
+ timeoutSeconds: 3
328
+ successThreshold: 1
329
+ failureThreshold: 5
330
+ ```
331
+
332
+ ## Capacity Planning For Production
333
+ <a id="capacity"></a>
334
+
335
+ In order to rightsize the production environment for your Fastify application,
336
+ it is highly recommended that you perform your own measurements against
337
+ different configurations of the environment, which may
338
+ use real CPU cores, virtual CPU cores (vCPU), or even fractional
339
+ vCPU cores. We will use the term vCPU throughout this
340
+ recommendation to represent any CPU type.
341
+
342
+ Tools such as [k6](https://github.com/grafana/k6)
343
+ or [autocannon](https://github.com/mcollina/autocannon) can be used for
344
+ conducting the necessary performance tests.
345
+
346
+ That said, you may also consider the following as a rule of thumb:
347
+
348
+ * To have the lowest possible latency, 2 vCPU are recommended per app
349
+ instance (e.g., a k8s pod). The second vCPU will mostly be used by the
350
+ garbage collector (GC) and libuv threadpool. This will minimize the latency
351
+ for your users, as well as the memory usage, as the GC will be run more
352
+ frequently. Also, the main thread won't have to stop to let the GC run.
353
+
354
+ * To optimize for throughput (handling the largest possible amount of
355
+ requests per second per vCPU available), consider using a smaller amount of vCPUs
356
+ per app instance. It is totally fine to run Node.js applications with 1 vCPU.
357
+
358
+ * You may experiment with an even smaller amount of vCPU, which may provide
359
+ even better throughput in certain use-cases. There are reports of API gateway
360
+ solutions working well with 100m-200m vCPU in Kubernetes.
361
+
362
+ See [Node's Event Loop From the Inside Out ](https://www.youtube.com/watch?v=P9csgxBgaZ8)
363
+ to understand the workings of Node.js in greater detail and make a
364
+ better determination about what your specific application needs.
365
+
366
+ ## Running Multiple Instances
367
+ <a id="multiple"></a>
368
+
369
+ There are several use-cases where running multiple Fastify
370
+ apps on the same server might be considered. A common example
371
+ would be exposing metrics endpoints on a separate port,
372
+ to prevent public access, when using a reverse proxy or an ingress
373
+ firewall is not an option.
374
+
375
+ It is perfectly fine to spin up several Fastify instances within the same
376
+ Node.js process and run them concurrently, even in high load systems.
377
+ Each Fastify instance only generates as much load as the traffic it receives,
378
+ plus the memory used for that Fastify instance.