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,604 @@
1
+ <h1 align="center">Serverless</h1>
2
+
3
+ Run serverless applications and REST APIs using your existing Fastify
4
+ application. You may need to make code changes to work on your
5
+ serverless platform of choice. This document contains a small guide
6
+ for the most popular serverless providers and how to use
7
+ Fastify with them.
8
+
9
+ #### Should you use Fastify in a serverless platform?
10
+
11
+ That is up to you! Keep in mind, functions as a service should always use
12
+ small and focused functions, but you can also run an entire web application with
13
+ them. It is important to remember that the bigger the application the slower the
14
+ initial boot will be. The best way to run Fastify applications in serverless
15
+ environments is to use platforms like Google Cloud Run, AWS Fargate, Azure
16
+ Container Instances, and Vercel where the server can handle multiple requests
17
+ at the same time and make full use of Fastify's features.
18
+
19
+ One of the best features of using Fastify in serverless applications is the ease
20
+ of development. In your local environment, you will always run the Fastify
21
+ application directly without the need for any additional tools, while the same
22
+ code will be executed in your serverless platform of choice with an additional
23
+ snippet of code.
24
+
25
+ ### Contents
26
+
27
+ - [AWS](#aws)
28
+ - [Genezio](#genezio)
29
+ - [Google Cloud Functions](#google-cloud-functions)
30
+ - [Google Firebase Functions](#google-firebase-functions)
31
+ - [Google Cloud Run](#google-cloud-run)
32
+ - [Netlify Lambda](#netlify-lambda)
33
+ - [Vercel](#vercel)
34
+
35
+ ## AWS
36
+
37
+ To integrate with AWS, you have two choices of library:
38
+
39
+ - Using [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify)
40
+ which only adds API Gateway support but has heavy optimizations for fastify.
41
+ - Using [@h4ad/serverless-adapter](https://github.com/H4ad/serverless-adapter)
42
+ which is a little slower as it creates an HTTP request for each AWS event but
43
+ has support for more AWS services such as: AWS SQS, AWS SNS and others.
44
+
45
+ So you can decide which option is best for you, but you can test both libraries.
46
+
47
+ ### Using @fastify/aws-lambda
48
+
49
+ The sample provided allows you to easily build serverless web
50
+ applications/services and RESTful APIs using Fastify on top of AWS Lambda and
51
+ Amazon API Gateway.
52
+
53
+ #### app.js
54
+
55
+ ```js
56
+ const fastify = require('fastify');
57
+
58
+ function init() {
59
+ const app = fastify();
60
+ app.get('/', (request, reply) => reply.send({ hello: 'world' }));
61
+ return app;
62
+ }
63
+
64
+ if (require.main === module) {
65
+ // called directly i.e. "node app"
66
+ init().listen({ port: 3000 }, (err) => {
67
+ if (err) console.error(err);
68
+ console.log('server listening on 3000');
69
+ });
70
+ } else {
71
+ // required as a module => executed on aws lambda
72
+ module.exports = init;
73
+ }
74
+ ```
75
+
76
+ When executed in your lambda function we do not need to listen to a specific
77
+ port, so we just export the wrapper function `init` in this case. The
78
+ [`lambda.js`](#lambdajs) file will use this export.
79
+
80
+ When you execute your Fastify application like always, i.e. `node app.js` *(the
81
+ detection for this could be `require.main === module`)*, you can normally listen
82
+ to your port, so you can still run your Fastify function locally.
83
+
84
+ #### lambda.js
85
+
86
+ ```js
87
+ const awsLambdaFastify = require('@fastify/aws-lambda')
88
+ const init = require('./app');
89
+
90
+ const proxy = awsLambdaFastify(init())
91
+ // or
92
+ // const proxy = awsLambdaFastify(init(), { binaryMimeTypes: ['application/octet-stream'] })
93
+
94
+ exports.handler = proxy;
95
+ // or
96
+ // exports.handler = (event, context, callback) => proxy(event, context, callback);
97
+ // or
98
+ // exports.handler = (event, context) => proxy(event, context);
99
+ // or
100
+ // exports.handler = async (event, context) => proxy(event, context);
101
+ ```
102
+
103
+ We just require
104
+ [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify) (make sure
105
+ you install the dependency `npm i @fastify/aws-lambda`) and our
106
+ [`app.js`](#appjs) file and call the exported `awsLambdaFastify` function with
107
+ the `app` as the only parameter. The resulting `proxy` function has the correct
108
+ signature to be used as a lambda `handler` function. This way all the incoming
109
+ events (API Gateway requests) are passed to the `proxy` function of
110
+ [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify).
111
+
112
+ #### Example
113
+
114
+ An example deployable with
115
+ [claudia.js](https://claudiajs.com/tutorials/serverless-express.html) can be
116
+ found
117
+ [here](https://github.com/claudiajs/example-projects/tree/master/fastify-app-lambda).
118
+
119
+ ### Considerations
120
+
121
+ - API Gateway does not support streams yet, so you are not able to handle
122
+ [streams](../Reference/Reply.md#streams).
123
+ - API Gateway has a timeout of 29 seconds, so it is important to provide a reply
124
+ during this time.
125
+
126
+ #### Beyond API Gateway
127
+
128
+ If you need to integrate with more AWS services, take a look at
129
+ [@h4ad/serverless-adapter](https://viniciusl.com.br/serverless-adapter/docs/main/frameworks/fastify)
130
+ on Fastify to find out how to integrate.
131
+
132
+ ## Genezio
133
+
134
+ [Genezio](https://genezio.com/) is a platform designed to simplify the deployment
135
+ of serverless applications to the cloud.
136
+
137
+ [Genezio has a dedicated guide for deploying a Fastify application.](https://genezio.com/docs/frameworks/fastify/)
138
+
139
+ ## Google Cloud Functions
140
+
141
+ ### Creation of Fastify instance
142
+ ```js
143
+ const fastify = require("fastify")({
144
+ logger: true // you can also define the level passing an object configuration to logger: {level: 'debug'}
145
+ });
146
+ ```
147
+
148
+ ### Add Custom `contentTypeParser` to Fastify instance
149
+
150
+ As explained [in issue
151
+ #946](https://github.com/fastify/fastify/issues/946#issuecomment-766319521),
152
+ since the Google Cloud Functions platform parses the body of the request before
153
+ it arrives at the Fastify instance, troubling the body request in case of `POST`
154
+ and `PATCH` methods, you need to add a custom [`Content-Type
155
+ Parser`](../Reference/ContentTypeParser.md) to mitigate this behavior.
156
+
157
+ ```js
158
+ fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
159
+ done(null, body.body);
160
+ });
161
+ ```
162
+
163
+ ### Define your endpoint (examples)
164
+
165
+ A simple `GET` endpoint:
166
+ ```js
167
+ fastify.get('/', async (request, reply) => {
168
+ reply.send({message: 'Hello World!'})
169
+ })
170
+ ```
171
+
172
+ Or a more complete `POST` endpoint with schema validation:
173
+ ```js
174
+ fastify.route({
175
+ method: 'POST',
176
+ url: '/hello',
177
+ schema: {
178
+ body: {
179
+ type: 'object',
180
+ properties: {
181
+ name: { type: 'string'}
182
+ },
183
+ required: ['name']
184
+ },
185
+ response: {
186
+ 200: {
187
+ type: 'object',
188
+ properties: {
189
+ message: {type: 'string'}
190
+ }
191
+ }
192
+ },
193
+ },
194
+ handler: async (request, reply) => {
195
+ const { name } = request.body;
196
+ reply.code(200).send({
197
+ message: `Hello ${name}!`
198
+ })
199
+ }
200
+ })
201
+ ```
202
+
203
+ ### Implement and export the function
204
+
205
+ Final step, implement the function to handle the request and pass it to Fastify
206
+ by emitting `request` event to `fastify.server`:
207
+
208
+ ```js
209
+ const fastifyFunction = async (request, reply) => {
210
+ await fastify.ready();
211
+ fastify.server.emit('request', request, reply)
212
+ }
213
+
214
+ exports.fastifyFunction = fastifyFunction;
215
+ ```
216
+
217
+ ### Local test
218
+
219
+ Install [Google Functions Framework for
220
+ Node.js](https://github.com/GoogleCloudPlatform/functions-framework-nodejs).
221
+
222
+ You can install it globally:
223
+ ```bash
224
+ npm i -g @google-cloud/functions-framework
225
+ ```
226
+
227
+ Or as a development library:
228
+ ```bash
229
+ npm i -D @google-cloud/functions-framework
230
+ ```
231
+
232
+ Then you can run your function locally with Functions Framework:
233
+ ```bash
234
+ npx @google-cloud/functions-framework --target=fastifyFunction
235
+ ```
236
+
237
+ Or add this command to your `package.json` scripts:
238
+ ```json
239
+ "scripts": {
240
+ ...
241
+ "dev": "npx @google-cloud/functions-framework --target=fastifyFunction"
242
+ ...
243
+ }
244
+ ```
245
+ and run it with `npm run dev`.
246
+
247
+ ### Deploy
248
+ ```bash
249
+ gcloud functions deploy fastifyFunction \
250
+ --runtime nodejs14 --trigger-http --region $GOOGLE_REGION --allow-unauthenticated
251
+ ```
252
+
253
+ #### Read logs
254
+ ```bash
255
+ gcloud functions logs read
256
+ ```
257
+
258
+ #### Example request to `/hello` endpoint
259
+ ```bash
260
+ curl -X POST https://$GOOGLE_REGION-$GOOGLE_PROJECT.cloudfunctions.net/me \
261
+ -H "Content-Type: application/json" \
262
+ -d '{ "name": "Fastify" }'
263
+ {"message":"Hello Fastify!"}
264
+ ```
265
+
266
+ ### References
267
+ - [Google Cloud Functions - Node.js Quickstart
268
+ ](https://cloud.google.com/functions/docs/quickstart-nodejs)
269
+
270
+ ## Google Firebase Functions
271
+
272
+ Follow this guide if you want to use Fastify as the HTTP framework for
273
+ Firebase Functions instead of the vanilla JavaScript router provided with
274
+ `onRequest(async (req, res) => {}`.
275
+
276
+ ### The onRequest() handler
277
+
278
+ We use the `onRequest` function to wrap our Fastify application instance.
279
+
280
+ As such, we'll begin with importing it to the code:
281
+
282
+ ```js
283
+ const { onRequest } = require("firebase-functions/v2/https")
284
+ ```
285
+
286
+ ### Creation of Fastify instance
287
+
288
+ Create the Fastify instance and encapsulate the returned application instance
289
+ in a function that will register routes, await the server's processing of
290
+ plugins, hooks, and other settings. As follows:
291
+
292
+ ```js
293
+ const fastify = require("fastify")({
294
+ logger: true,
295
+ })
296
+
297
+ const fastifyApp = async (request, reply) => {
298
+ await registerRoutes(fastify)
299
+ await fastify.ready()
300
+ fastify.server.emit("request", request, reply)
301
+ }
302
+ ```
303
+
304
+ ### Add Custom `contentTypeParser` to Fastify instance and define endpoints
305
+
306
+ Firebase Function's HTTP layer already parses the request and makes a JSON
307
+ payload available through the property `payload.body` below. It also provides
308
+ access to the raw body, unparsed, which is useful for calculating request
309
+ signatures to validate HTTP webhooks.
310
+
311
+ Add as follows to the `registerRoutes()` function:
312
+
313
+ ```js
314
+ async function registerRoutes (fastify) {
315
+ fastify.addContentTypeParser("application/json", {}, (req, payload, done) => {
316
+ // useful to include the request's raw body on the `req` object that will
317
+ // later be available in your other routes so you can calculate the HMAC
318
+ // if needed
319
+ req.rawBody = payload.rawBody
320
+
321
+ // payload.body is already the parsed JSON so we just fire the done callback
322
+ // with it
323
+ done(null, payload.body)
324
+ })
325
+
326
+ // define your endpoints here...
327
+ fastify.post("/some-route-here", async (request, reply) => {})
328
+
329
+ fastify.get('/', async (request, reply) => {
330
+ reply.send({message: 'Hello World!'})
331
+ })
332
+ }
333
+ ```
334
+
335
+ **Failing to add this `ContentTypeParser` may lead to the Fastify process
336
+ remaining stuck and not processing any other requests after receiving one with
337
+ the Content-Type `application/json`.**
338
+
339
+ When using Typescript, since the type of `payload` is a native `IncomingMessage`
340
+ that gets modified by Firebase, it won't be able to find the property
341
+ `payload.body`.
342
+
343
+ In order to suppress the error, you can use the following signature:
344
+
345
+ ```ts
346
+ declare module 'http' {
347
+ interface IncomingMessage {
348
+ body?: unknown;
349
+ }
350
+ }
351
+ ```
352
+
353
+ ### Export the function using Firebase onRequest
354
+
355
+ Final step is to export the Fastify app instance to Firebase's own
356
+ `onRequest()` function so it can pass the request and reply objects to it:
357
+
358
+ ```js
359
+ exports.app = onRequest(fastifyApp)
360
+ ```
361
+
362
+ ### Local test
363
+
364
+ Install the Firebase tools functions so you can use the CLI:
365
+
366
+ ```bash
367
+ npm i -g firebase-tools
368
+ ```
369
+
370
+ Then you can run your function locally with:
371
+
372
+ ```bash
373
+ firebase emulators:start --only functions
374
+ ```
375
+
376
+ ### Deploy
377
+
378
+ Deploy your Firebase Functions with:
379
+
380
+ ```bash
381
+ firebase deploy --only functions
382
+ ```
383
+
384
+ #### Read logs
385
+
386
+ Use the Firebase tools CLI:
387
+
388
+ ```bash
389
+ firebase functions:log
390
+ ```
391
+
392
+ ### References
393
+ - [Fastify on Firebase Functions](https://github.com/lirantal/lemon-squeezy-firebase-webhook-fastify/blob/main/package.json)
394
+ - [An article about HTTP webhooks on Firebase Functions and Fastify: A Practical Case Study with Lemon Squeezy](https://lirantal.com/blog/http-webhooks-firebase-functions-fastify-practical-case-study-lemon-squeezy)
395
+
396
+ ## Google Cloud Run
397
+
398
+ Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless
399
+ **container** environment. Its primary purpose is to provide an
400
+ infrastructure-abstracted environment to run arbitrary containers. As a result,
401
+ Fastify can be deployed to Google Cloud Run with little-to-no code changes from
402
+ the way you would write your Fastify app normally.
403
+
404
+ *Follow the steps below to deploy to Google Cloud Run if you are already
405
+ familiar with gcloud or just follow their
406
+ [quickstart](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)*.
407
+
408
+ ### Adjust Fastify server
409
+
410
+ For Fastify to properly listen for requests within the container, be
411
+ sure to set the correct port and address:
412
+
413
+ ```js
414
+ function build() {
415
+ const fastify = Fastify({ trustProxy: true })
416
+ return fastify
417
+ }
418
+
419
+ async function start() {
420
+ // Google Cloud Run will set this environment variable for you, so
421
+ // you can also use it to detect if you are running in Cloud Run
422
+ const IS_GOOGLE_CLOUD_RUN = process.env.K_SERVICE !== undefined
423
+
424
+ // You must listen on the port Cloud Run provides
425
+ const port = process.env.PORT || 3000
426
+
427
+ // You must listen on all IPV4 addresses in Cloud Run
428
+ const host = IS_GOOGLE_CLOUD_RUN ? "0.0.0.0" : undefined
429
+
430
+ try {
431
+ const server = build()
432
+ const address = await server.listen({ port, host })
433
+ console.log(`Listening on ${address}`)
434
+ } catch (err) {
435
+ console.error(err)
436
+ process.exit(1)
437
+ }
438
+ }
439
+
440
+ module.exports = build
441
+
442
+ if (require.main === module) {
443
+ start()
444
+ }
445
+ ```
446
+
447
+ ### Add a Dockerfile
448
+
449
+ You can add any valid `Dockerfile` that packages and runs a Node app. A basic
450
+ `Dockerfile` can be found in the official [gcloud
451
+ docs](https://github.com/knative/docs/blob/2d654d1fd6311750cc57187a86253c52f273d924/docs/serving/samples/hello-world/helloworld-nodejs/Dockerfile).
452
+
453
+ ```Dockerfile
454
+ # Use the official Node.js 10 image.
455
+ # https://hub.docker.com/_/node
456
+ FROM node:10
457
+
458
+ # Create and change to the app directory.
459
+ WORKDIR /usr/src/app
460
+
461
+ # Copy application dependency manifests to the container image.
462
+ # A wildcard is used to ensure both package.json AND package-lock.json are copied.
463
+ # Copying this separately prevents re-running npm install on every code change.
464
+ COPY package*.json ./
465
+
466
+ # Install production dependencies.
467
+ RUN npm i --production
468
+
469
+ # Copy local code to the container image.
470
+ COPY . .
471
+
472
+ # Run the web service on container startup.
473
+ CMD [ "npm", "start" ]
474
+ ```
475
+
476
+ ### Add a .dockerignore
477
+
478
+ To keep build artifacts out of your container (which keeps it small and improves
479
+ build times) add a `.dockerignore` file like the one below:
480
+
481
+ ```dockerignore
482
+ Dockerfile
483
+ README.md
484
+ node_modules
485
+ npm-debug.log
486
+ ```
487
+
488
+ ### Submit build
489
+
490
+ Next, submit your app to be built into a Docker image by running the following
491
+ command (replacing `PROJECT-ID` and `APP-NAME` with your GCP project id and an
492
+ app name):
493
+
494
+ ```bash
495
+ gcloud builds submit --tag gcr.io/PROJECT-ID/APP-NAME
496
+ ```
497
+
498
+ ### Deploy Image
499
+
500
+ After your image has built, you can deploy it with the following command:
501
+
502
+ ```bash
503
+ gcloud beta run deploy --image gcr.io/PROJECT-ID/APP-NAME --platform managed
504
+ ```
505
+
506
+ Your app will be accessible from the URL GCP provides.
507
+
508
+ ## netlify-lambda
509
+
510
+ First, please perform all preparation steps related to **AWS Lambda**.
511
+
512
+ Create a folder called `functions`, then create `server.js` (and your endpoint
513
+ path will be `server.js`) inside the `functions` folder.
514
+
515
+ ### functions/server.js
516
+
517
+ ```js
518
+ export { handler } from '../lambda.js'; // Change `lambda.js` path to your `lambda.js` path
519
+ ```
520
+
521
+ ### netlify.toml
522
+
523
+ ```toml
524
+ [build]
525
+ # This will be run the site build
526
+ command = "npm run build:functions"
527
+ # This is the directory is publishing to netlify's CDN
528
+ # and this is directory of your front of your app
529
+ # publish = "build"
530
+ # functions build directory
531
+ functions = "functions-build" # always appends `-build` folder to your `functions` folder for builds
532
+ ```
533
+
534
+ ### webpack.config.netlify.js
535
+
536
+ **Do not forget to add this Webpack config, or else problems may occur**
537
+
538
+ ```js
539
+ const nodeExternals = require('webpack-node-externals');
540
+ const dotenv = require('dotenv-safe');
541
+ const webpack = require('webpack');
542
+
543
+ const env = process.env.NODE_ENV || 'production';
544
+ const dev = env === 'development';
545
+
546
+ if (dev) {
547
+ dotenv.config({ allowEmptyValues: true });
548
+ }
549
+
550
+ module.exports = {
551
+ mode: env,
552
+ devtool: dev ? 'eval-source-map' : 'none',
553
+ externals: [nodeExternals()],
554
+ devServer: {
555
+ proxy: {
556
+ '/.netlify': {
557
+ target: 'http://localhost:9000',
558
+ pathRewrite: { '^/.netlify/functions': '' }
559
+ }
560
+ }
561
+ },
562
+ module: {
563
+ rules: []
564
+ },
565
+ plugins: [
566
+ new webpack.DefinePlugin({
567
+ 'process.env.APP_ROOT_PATH': JSON.stringify('/'),
568
+ 'process.env.NETLIFY_ENV': true,
569
+ 'process.env.CONTEXT': env
570
+ })
571
+ ]
572
+ };
573
+ ```
574
+
575
+ ### Scripts
576
+
577
+ Add this command to your `package.json` *scripts*
578
+
579
+ ```json
580
+ "scripts": {
581
+ ...
582
+ "build:functions": "netlify-lambda build functions --config ./webpack.config.netlify.js"
583
+ ...
584
+ }
585
+ ```
586
+
587
+ Then it should work fine.
588
+
589
+ ## Vercel
590
+
591
+ [Vercel](https://vercel.com) fully supports deploying Fastify applications.
592
+ Additionally, with Vercel's
593
+ [Fluid compute](https://vercel.com/docs/functions/fluid-compute), you can combine
594
+ server-like concurrency with the autoscaling properties of traditional
595
+ serverless functions.
596
+
597
+ Get started with the
598
+ [Fastify template on Vercel](
599
+ https://vercel.com/templates/backend/fastify-on-vercel).
600
+
601
+ [Fluid compute](https://vercel.com/docs/functions/fluid-compute) currently
602
+ requires an explicit opt-in. Learn more about enabling Fluid compute
603
+ [here](
604
+ https://vercel.com/docs/fluid-compute#enabling-fluid-compute).