fastify 5.8.0 → 5.8.2
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.
- package/docs/Guides/Ecosystem.md +10 -0
- package/docs/Guides/Migration-Guide-V4.md +8 -13
- package/docs/Reference/ContentTypeParser.md +7 -0
- package/docs/Reference/Server.md +4 -1
- package/docs/Reference/Validation-and-Serialization.md +38 -1
- package/fastify.js +1 -1
- package/lib/content-type.js +13 -5
- package/package.json +2 -2
- package/test/content-type.test.js +38 -0
- package/AGENTS.md +0 -290
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -188,6 +188,9 @@ section.
|
|
|
188
188
|
A Fastify plugin that protects against No(n)SQL injection by sanitizing data.
|
|
189
189
|
- [`@exortek/remix-fastify`](https://github.com/ExorTek/remix-fastify)
|
|
190
190
|
Fastify plugin for Remix.
|
|
191
|
+
- [`@glidemq/fastify`](https://github.com/avifenesh/glidemq-fastify)
|
|
192
|
+
Queue management plugin for glide-mq with REST API endpoints, SSE events,
|
|
193
|
+
and in-memory testing mode. Powered by Valkey/Redis Streams.
|
|
191
194
|
- [`@gquittet/graceful-server`](https://github.com/gquittet/graceful-server)
|
|
192
195
|
Tiny (~5k), Fast, KISS, and dependency-free Node.js library to make your
|
|
193
196
|
Fastify API graceful.
|
|
@@ -207,6 +210,9 @@ section.
|
|
|
207
210
|
A Fastify plugin that enforces naming pattern for routes path.
|
|
208
211
|
- [`@joggr/fastify-prisma`](https://github.com/joggrdocs/fastify-prisma)
|
|
209
212
|
A plugin for accessing an instantiated PrismaClient on your server.
|
|
213
|
+
- [`@matths/fastify-svelte-view`](https://github.com/matths/fastify-svelte-view)
|
|
214
|
+
A Fastify plugin for rendering Svelte components with support for SSR
|
|
215
|
+
(Server-Side Rendering), CSR (Client-Side Rendering), and SSR with hydration.
|
|
210
216
|
- [`@mgcrea/fastify-graceful-exit`](https://github.com/mgcrea/fastify-graceful-exit)
|
|
211
217
|
A plugin to close the server gracefully
|
|
212
218
|
- [`@mgcrea/fastify-request-logger`](https://github.com/mgcrea/fastify-request-logger)
|
|
@@ -225,6 +231,8 @@ section.
|
|
|
225
231
|
Beautiful OpenAPI/Swagger API references for Fastify
|
|
226
232
|
- [`@trubavuong/fastify-seaweedfs`](https://github.com/trubavuong/fastify-seaweedfs)
|
|
227
233
|
SeaweedFS for Fastify
|
|
234
|
+
- [`@yeliex/fastify-problem-details`](https://github.com/yeliex/fastify-problem-details)
|
|
235
|
+
RFC 9457 Problem Details implementation for Fastify, with typed HTTP errors.
|
|
228
236
|
- [`apitally`](https://github.com/apitally/apitally-js) Fastify plugin to
|
|
229
237
|
integrate with [Apitally](https://apitally.io/fastify), an API analytics,
|
|
230
238
|
logging and monitoring tool.
|
|
@@ -366,6 +374,8 @@ section.
|
|
|
366
374
|
Fastify feature flags plugin with multiple providers support (e.g. env,
|
|
367
375
|
[config](https://lorenwest.github.io/node-config/),
|
|
368
376
|
[unleash](https://github.com/Unleash/unleash)).
|
|
377
|
+
- [`fastify-file-router`](https://github.com/bhouston/fastify-file-router)
|
|
378
|
+
A typesafe TanStack Start / Next.JS-style router with JSON + Zod schema support.
|
|
369
379
|
- [`fastify-file-routes`](https://github.com/spa5k/fastify-file-routes) Get
|
|
370
380
|
Next.js based file system routing into fastify.
|
|
371
381
|
- [`fastify-formidable`](https://github.com/climba03003/fastify-formidable)
|
|
@@ -14,24 +14,19 @@ To help with the upgrade, we’ve worked with the team at
|
|
|
14
14
|
publish codemods that will automatically update your code to many of
|
|
15
15
|
the new APIs and patterns in Fastify v4.
|
|
16
16
|
|
|
17
|
-
Run the following
|
|
18
|
-
[migration recipe](https://go.codemod.com/fastify-4-migration-recipe) to
|
|
19
|
-
automatically update your code to Fastify v4:
|
|
20
17
|
|
|
21
|
-
```
|
|
18
|
+
```bash
|
|
22
19
|
npx codemod@latest fastify/4/migration-recipe
|
|
23
20
|
```
|
|
21
|
+
This applies the following codemods:
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- [`fastify/4/wrap-routes-plugin`](https://go.codemod.com/fastify-4-wrap-routes-plugin)
|
|
30
|
-
- [`fastify/4/await-register-calls`](https://go.codemod.com/fastify-4-await-register-calls)
|
|
23
|
+
- fastify/4/remove-app-use
|
|
24
|
+
- fastify/4/reply-raw-access
|
|
25
|
+
- fastify/4/wrap-routes-plugin
|
|
26
|
+
- fastify/4/await-register-calls
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
see [Codemod Registry](https://go.codemod.com/fastify).
|
|
28
|
+
For information on the migration recipe, see
|
|
29
|
+
https://app.codemod.com/registry/fastify/4/migration-recipe.
|
|
35
30
|
|
|
36
31
|
|
|
37
32
|
## Breaking Changes
|
|
@@ -17,6 +17,13 @@ declared in a plugin, it is available only in that scope and its children.
|
|
|
17
17
|
Fastify automatically adds the parsed request payload to the [Fastify
|
|
18
18
|
request](./Request.md) object, accessible via `request.body`.
|
|
19
19
|
|
|
20
|
+
> **Important:** When using a body schema with the
|
|
21
|
+
> [`content`](./Validation-and-Serialization.md#body-content-type-validation)
|
|
22
|
+
> property to validate per content type, only content types listed in the schema
|
|
23
|
+
> will be validated. If you add a custom content type parser but do not include
|
|
24
|
+
> its content type in the body schema's `content` property, the incoming data
|
|
25
|
+
> will be parsed but **not validated**.
|
|
26
|
+
|
|
20
27
|
Note that for `GET` and `HEAD` requests, the payload is never parsed. For
|
|
21
28
|
`OPTIONS` and `DELETE` requests, the payload is parsed only if a valid
|
|
22
29
|
`content-type` header is provided. Unlike `POST`, `PUT`, and `PATCH`, the
|
package/docs/Reference/Server.md
CHANGED
|
@@ -1784,7 +1784,10 @@ call is encapsulated by prefix, so different plugins can set different not found
|
|
|
1784
1784
|
handlers if a different [`prefix` option](./Plugins.md#route-prefixing-option)
|
|
1785
1785
|
is passed to `fastify.register()`. The handler is treated as a regular route
|
|
1786
1786
|
handler so requests will go through the full [Fastify
|
|
1787
|
-
lifecycle](./Lifecycle.md#lifecycle)
|
|
1787
|
+
lifecycle](./Lifecycle.md#lifecycle) for unexisting URLs.
|
|
1788
|
+
*async-await* is supported as well.
|
|
1789
|
+
Badly formatted URLs are sent to the [`onBadUrl`](#onbadurl)
|
|
1790
|
+
handler instead.
|
|
1788
1791
|
|
|
1789
1792
|
You can also register [`preValidation`](./Hooks.md#route-hooks) and
|
|
1790
1793
|
[`preHandler`](./Hooks.md#route-hooks) hooks for the 404 handler.
|
|
@@ -5,7 +5,11 @@ Fastify uses a schema-based approach. We recommend using
|
|
|
5
5
|
[JSON Schema](https://json-schema.org/) to validate routes and serialize outputs.
|
|
6
6
|
Fastify compiles the schema into a highly performant function.
|
|
7
7
|
|
|
8
|
-
Validation is only attempted if the content type is `application/json
|
|
8
|
+
Validation is only attempted if the content type is `application/json`,
|
|
9
|
+
unless the body schema uses the [`content`](#body-content-type-validation)
|
|
10
|
+
property to specify validation per content type. When the body schema defines
|
|
11
|
+
a `content` field, it must enumerate all possible content types the
|
|
12
|
+
application expects to handle with the associated handler.
|
|
9
13
|
|
|
10
14
|
All examples use the
|
|
11
15
|
[JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7)
|
|
@@ -228,6 +232,9 @@ const schema = {
|
|
|
228
232
|
fastify.post('/the/url', { schema }, handler)
|
|
229
233
|
```
|
|
230
234
|
|
|
235
|
+
#### Body Content-Type Validation
|
|
236
|
+
<a id="body-content-type-validation"></a>
|
|
237
|
+
|
|
231
238
|
For `body` schema, it is further possible to differentiate the schema per content
|
|
232
239
|
type by nesting the schemas inside `content` property. The schema validation
|
|
233
240
|
will be applied based on the `Content-Type` header in the request.
|
|
@@ -250,6 +257,36 @@ fastify.post('/the/url', {
|
|
|
250
257
|
}, handler)
|
|
251
258
|
```
|
|
252
259
|
|
|
260
|
+
> **Important:** When using [custom content type
|
|
261
|
+
> parsers](./ContentTypeParser.md), the parsed body will **only** be validated
|
|
262
|
+
> if the request's content type is listed in the `content` object above. If
|
|
263
|
+
> a parser for a content type (e.g., `application/yaml`) is defined,
|
|
264
|
+
> but it is not not included in the body schema's `content` property,
|
|
265
|
+
> the incoming data will be parsed but **not validated**.
|
|
266
|
+
>
|
|
267
|
+
> ```js
|
|
268
|
+
> // Add a custom parser for YAML
|
|
269
|
+
> fastify.addContentTypeParser('application/yaml', { parseAs: 'string' }, (req, body, done) => {
|
|
270
|
+
> done(null, YAML.parse(body))
|
|
271
|
+
> })
|
|
272
|
+
>
|
|
273
|
+
> fastify.post('/the/url', {
|
|
274
|
+
> schema: {
|
|
275
|
+
> body: {
|
|
276
|
+
> content: {
|
|
277
|
+
> 'application/json': {
|
|
278
|
+
> schema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] }
|
|
279
|
+
> },
|
|
280
|
+
> // Without this entry, application/yaml requests will NOT be validated
|
|
281
|
+
> 'application/yaml': {
|
|
282
|
+
> schema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] }
|
|
283
|
+
> }
|
|
284
|
+
> }
|
|
285
|
+
> }
|
|
286
|
+
> }
|
|
287
|
+
> }, handler)
|
|
288
|
+
> ```
|
|
289
|
+
|
|
253
290
|
Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) values to
|
|
254
291
|
the types specified in the schema `type` keywords, both to pass validation and
|
|
255
292
|
to use the correctly typed data afterwards.
|
package/fastify.js
CHANGED
package/lib/content-type.js
CHANGED
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* keyValuePairsReg is used to split the parameters list into associated
|
|
5
|
-
* key value pairings.
|
|
5
|
+
* key value pairings. The leading `(?:^|;)\s*` anchor ensures the regex
|
|
6
|
+
* only attempts matches at parameter boundaries, preventing quadratic
|
|
7
|
+
* backtracking on malformed input.
|
|
6
8
|
*
|
|
7
9
|
* @see https://httpwg.org/specs/rfc9110.html#parameter
|
|
8
10
|
* @type {RegExp}
|
|
9
11
|
*/
|
|
10
|
-
const keyValuePairsReg = /([\w!#$%&'*+.^`|~-]+)=([^;]*)/gm
|
|
12
|
+
const keyValuePairsReg = /(?:^|;)\s*([\w!#$%&'*+.^`|~-]+)=([^;]*)/gm
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* typeNameReg is used to validate that the first part of the media-type
|
|
14
|
-
* does not use disallowed characters.
|
|
16
|
+
* does not use disallowed characters. Types must consist solely of
|
|
17
|
+
* characters that match the specified character class. It must terminate
|
|
18
|
+
* with a matching character.
|
|
15
19
|
*
|
|
16
20
|
* @see https://httpwg.org/specs/rfc9110.html#rule.token.separators
|
|
17
21
|
* @type {RegExp}
|
|
@@ -20,12 +24,16 @@ const typeNameReg = /^[\w!#$%&'*+.^`|~-]+$/
|
|
|
20
24
|
|
|
21
25
|
/**
|
|
22
26
|
* subtypeNameReg is used to validate that the second part of the media-type
|
|
23
|
-
* does not use disallowed characters.
|
|
27
|
+
* does not use disallowed characters. Subtypes must consist solely of
|
|
28
|
+
* characters that match the specified character class, and optionally
|
|
29
|
+
* terminated with any amount of whitespace characters. Without the terminating
|
|
30
|
+
* anchor (`$`), the regular expression will match the leading portion of a
|
|
31
|
+
* string instead of the whole string.
|
|
24
32
|
*
|
|
25
33
|
* @see https://httpwg.org/specs/rfc9110.html#rule.token.separators
|
|
26
34
|
* @type {RegExp}
|
|
27
35
|
*/
|
|
28
|
-
const subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s
|
|
36
|
+
const subtypeNameReg = /^[\w!#$%&'*+.^`|~-]+\s*$/
|
|
29
37
|
|
|
30
38
|
/**
|
|
31
39
|
* ContentType parses and represents the value of the content-type header.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.2",
|
|
4
4
|
"description": "Fast and low overhead web framework, for Node.js",
|
|
5
5
|
"main": "fastify.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
"ajv-i18n": "^4.2.0",
|
|
178
178
|
"ajv-merge-patch": "^5.0.1",
|
|
179
179
|
"autocannon": "^8.0.0",
|
|
180
|
-
"borp": "^
|
|
180
|
+
"borp": "^0.21.0",
|
|
181
181
|
"branch-comparer": "^1.1.0",
|
|
182
182
|
"concurrently": "^9.1.2",
|
|
183
183
|
"cross-env": "^10.0.0",
|
|
@@ -74,6 +74,44 @@ describe('ContentType class', () => {
|
|
|
74
74
|
found = new ContentType('foo/π; param=1')
|
|
75
75
|
t.assert.equal(found.isEmpty, true)
|
|
76
76
|
t.assert.equal(found.isValid, false)
|
|
77
|
+
|
|
78
|
+
found = new ContentType('application/json<script>alert(1)</script>')
|
|
79
|
+
t.assert.equal(found.isEmpty, true)
|
|
80
|
+
t.assert.equal(found.isValid, false)
|
|
81
|
+
|
|
82
|
+
found = new ContentType('application/json/extra/slashes')
|
|
83
|
+
t.assert.equal(found.isEmpty, true)
|
|
84
|
+
t.assert.equal(found.isValid, false)
|
|
85
|
+
|
|
86
|
+
found = new ContentType('application/json(garbage)')
|
|
87
|
+
t.assert.equal(found.isEmpty, true)
|
|
88
|
+
t.assert.equal(found.isValid, false)
|
|
89
|
+
|
|
90
|
+
found = new ContentType('application/json@evil')
|
|
91
|
+
t.assert.equal(found.isEmpty, true)
|
|
92
|
+
t.assert.equal(found.isValid, false)
|
|
93
|
+
|
|
94
|
+
found = new ContentType('application/json\x00garbage')
|
|
95
|
+
t.assert.equal(found.isEmpty, true)
|
|
96
|
+
t.assert.equal(found.isValid, false)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test('subtype with multiple fields validates as incorrect', (t) => {
|
|
100
|
+
let found = new ContentType('application/json whatever')
|
|
101
|
+
t.assert.equal(found.isValid, false)
|
|
102
|
+
t.assert.equal(found.isEmpty, true)
|
|
103
|
+
|
|
104
|
+
found = new ContentType('application/ json whatever')
|
|
105
|
+
t.assert.equal(found.isValid, false)
|
|
106
|
+
t.assert.equal(found.isEmpty, true)
|
|
107
|
+
|
|
108
|
+
found = new ContentType('application/json whatever; foo=bar')
|
|
109
|
+
t.assert.equal(found.isValid, false)
|
|
110
|
+
t.assert.equal(found.isEmpty, true)
|
|
111
|
+
|
|
112
|
+
found = new ContentType('application/ json whatever; foo=bar')
|
|
113
|
+
t.assert.equal(found.isValid, false)
|
|
114
|
+
t.assert.equal(found.isEmpty, true)
|
|
77
115
|
})
|
|
78
116
|
|
|
79
117
|
test('returns a plain media type instance', (t) => {
|
package/AGENTS.md
DELETED
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
# AGENTS.md - Guide for AI Agents Working with Fastify
|
|
2
|
-
|
|
3
|
-
This document provides information and guidelines for AI agents (such as GitHub Copilot, Cursor, pi, or other AI coding assistants) working with the Fastify codebase.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
Fastify is a high-performance web framework for Node.js focused on:
|
|
8
|
-
- **Speed**: One of the fastest Node.js web frameworks
|
|
9
|
-
- **Extensibility**: Powerful plugin architecture with hooks and decorators
|
|
10
|
-
- **Schema-based**: JSON Schema validation and serialization
|
|
11
|
-
- **Developer experience**: Expressive API with minimal overhead
|
|
12
|
-
- **TypeScript support**: Full type definitions included
|
|
13
|
-
|
|
14
|
-
**Current Version**: 5.7.1 (main branch)
|
|
15
|
-
**Repository**: https://github.com/fastify/fastify
|
|
16
|
-
|
|
17
|
-
## Repository Structure
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
fastify/
|
|
21
|
-
├── docs/ # Documentation (Guides and Reference)
|
|
22
|
-
│ ├── Guides/ # Tutorials and how-to guides
|
|
23
|
-
│ └── Reference/ # API documentation
|
|
24
|
-
├── examples/ # Example applications and benchmarks
|
|
25
|
-
├── lib/ # Core library code
|
|
26
|
-
├── test/ # Test files
|
|
27
|
-
├── types/ # TypeScript type definitions
|
|
28
|
-
├── build/ # Build scripts
|
|
29
|
-
├── integration/ # Integration tests
|
|
30
|
-
├── fastify.js # Main entry point
|
|
31
|
-
├── fastify.d.ts # Main TypeScript definitions
|
|
32
|
-
└── package.json # Dependencies and scripts
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Key Files for Agents
|
|
36
|
-
|
|
37
|
-
### Core Files
|
|
38
|
-
- **`fastify.js`** - Main Fastify class and entry point
|
|
39
|
-
- **`fastify.d.ts`** - TypeScript type definitions (keep these in sync)
|
|
40
|
-
- **`lib/`** - All core functionality:
|
|
41
|
-
- `route.js` - Route handling
|
|
42
|
-
- `req-res.js` - Request and Reply objects
|
|
43
|
-
- `hooks.js` - Lifecycle hooks
|
|
44
|
-
- `plugin.js` - Plugin system
|
|
45
|
-
- `validation.js` - Schema validation
|
|
46
|
-
- `content-type-parser.js` - Body parsing
|
|
47
|
-
- `logger.js` - Pino logger integration
|
|
48
|
-
|
|
49
|
-
### Configuration Files
|
|
50
|
-
- **`package.json`** - Scripts, dependencies, and contributors
|
|
51
|
-
- **`eslint.config.js`** - Linting configuration (uses neostandard)
|
|
52
|
-
- **`.markdownlint-cli2.yaml`** - Markdown linting rules
|
|
53
|
-
|
|
54
|
-
### Documentation Files
|
|
55
|
-
- **`README.md`** - Project overview and quick start
|
|
56
|
-
- **`CONTRIBUTING.md`** - Contribution guidelines
|
|
57
|
-
- **`GOVERNANCE.md`** - Links to organization governance
|
|
58
|
-
- **`SECURITY.md`** - Security policy
|
|
59
|
-
- **`docs/Guides/Contributing.md`** - Detailed contributing guide
|
|
60
|
-
- **`docs/Guides/Style-Guide.md`** - Coding style conventions
|
|
61
|
-
|
|
62
|
-
## Testing Conventions
|
|
63
|
-
|
|
64
|
-
### Test Framework
|
|
65
|
-
Fastify uses **Borp** (a custom test runner) for testing.
|
|
66
|
-
|
|
67
|
-
### Test Structure
|
|
68
|
-
- Tests are in the **`test/`** directory
|
|
69
|
-
- Test files follow the pattern: `test/<module>.test.js`
|
|
70
|
-
- Integration tests are in **`integration/`** directory
|
|
71
|
-
|
|
72
|
-
### Running Tests
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# Run all tests
|
|
76
|
-
npm test
|
|
77
|
-
|
|
78
|
-
# Run unit tests only
|
|
79
|
-
npm run unit
|
|
80
|
-
|
|
81
|
-
# Run tests with coverage
|
|
82
|
-
npm run coverage
|
|
83
|
-
|
|
84
|
-
# Run tests in watch mode
|
|
85
|
-
npm run test:watch
|
|
86
|
-
|
|
87
|
-
# Run TypeScript type tests
|
|
88
|
-
npm run test:typescript
|
|
89
|
-
|
|
90
|
-
# Run CI tests (minimal)
|
|
91
|
-
npm run test:ci
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### Test Requirements
|
|
95
|
-
- **100% line coverage** is required for all changes (enforced by CI)
|
|
96
|
-
- Tests must pass on all supported Node.js versions
|
|
97
|
-
- TypeScript types must be tested (using `tsd`)
|
|
98
|
-
|
|
99
|
-
## Code Style and Conventions
|
|
100
|
-
|
|
101
|
-
### Linting
|
|
102
|
-
- Uses **Neostandard** JavaScript style guide
|
|
103
|
-
- ESLint is configured in `eslint.config.js`
|
|
104
|
-
- Run `npm run lint` to check code style
|
|
105
|
-
- Run `npm run lint:fix` to auto-fix issues
|
|
106
|
-
|
|
107
|
-
### Key Style Rules (from Style-Guide.md)
|
|
108
|
-
- Use `const` and `let`, never `var`
|
|
109
|
-
- Use arrow functions for callbacks
|
|
110
|
-
- Use async/await instead of promises
|
|
111
|
-
- Follow semicolon usage (neostandard enforces this)
|
|
112
|
-
- Use template literals for string interpolation
|
|
113
|
-
- Prefer functional methods (`map`, `filter`, `reduce`) over loops
|
|
114
|
-
- Error-first callback pattern for async operations where needed
|
|
115
|
-
|
|
116
|
-
### Naming Conventions
|
|
117
|
-
- **Files**: kebab-case (`content-type-parser.js`)
|
|
118
|
-
- **Variables**: camelCase
|
|
119
|
-
- **Constants**: UPPER_SNAKE_CASE
|
|
120
|
-
- **Classes**: PascalCase
|
|
121
|
-
- **Private methods**: prefixed with `_`
|
|
122
|
-
|
|
123
|
-
## Common Tasks
|
|
124
|
-
|
|
125
|
-
### Adding a New Feature
|
|
126
|
-
1. Implement the feature in `lib/`
|
|
127
|
-
2. Add tests in `test/`
|
|
128
|
-
3. Update TypeScript types in `fastify.d.ts` or `types/`
|
|
129
|
-
4. Update documentation in `docs/`
|
|
130
|
-
5. Run `npm test` to ensure all tests pass
|
|
131
|
-
6. Run `npm run lint` to check code style
|
|
132
|
-
7. Add changelog entry for release
|
|
133
|
-
|
|
134
|
-
### Fixing a Bug
|
|
135
|
-
1. Add a failing test case in `test/`
|
|
136
|
-
2. Fix the bug in `lib/`
|
|
137
|
-
3. Ensure all tests pass
|
|
138
|
-
4. Check if TypeScript types need updating
|
|
139
|
-
5. Update documentation if behavior changes
|
|
140
|
-
|
|
141
|
-
### Working with Plugins
|
|
142
|
-
- See `docs/Guides/Write-Plugin.md` for plugin authoring
|
|
143
|
-
- See `docs/Guides/Plugins-Guide.md` for plugin usage
|
|
144
|
-
- Plugin example: `lib/plugin.js`
|
|
145
|
-
|
|
146
|
-
## Architecture Highlights
|
|
147
|
-
|
|
148
|
-
### Core Components
|
|
149
|
-
|
|
150
|
-
1. **Server (`fastify.js`)**
|
|
151
|
-
- Main Fastify class
|
|
152
|
-
- Server initialization and configuration
|
|
153
|
-
- Plugin system integration (via `avvio`)
|
|
154
|
-
|
|
155
|
-
2. **Routing (`lib/route.js`)**
|
|
156
|
-
- Uses `find-my-way` for fast route matching
|
|
157
|
-
- Route registration and lookup
|
|
158
|
-
- Shorthand methods (get, post, put, delete, etc.)
|
|
159
|
-
|
|
160
|
-
3. **Request/Response (`lib/req-res.js`)**
|
|
161
|
-
- Request object extensions
|
|
162
|
-
- Reply object with fluent API
|
|
163
|
-
- Decorator support
|
|
164
|
-
|
|
165
|
-
4. **Hooks (`lib/hooks.js`)**
|
|
166
|
-
- Lifecycle hooks (onRequest, preHandler, etc.)
|
|
167
|
-
- Hook execution order and timing
|
|
168
|
-
|
|
169
|
-
5. **Validation (`lib/validation.js`)**
|
|
170
|
-
- JSON Schema validation via AJV
|
|
171
|
-
- Response serialization
|
|
172
|
-
- Built-in error serializer
|
|
173
|
-
|
|
174
|
-
6. **Content Type Parser (`lib/content-type-parser.js`)**
|
|
175
|
-
- Request body parsing
|
|
176
|
-
- Custom parser support
|
|
177
|
-
- JSON and other formats
|
|
178
|
-
|
|
179
|
-
### Plugin System
|
|
180
|
-
- Plugins are loaded asynchronously via `avvio`
|
|
181
|
-
- Supports encapsulation (scoped plugins)
|
|
182
|
-
- Hooks and decorators can be scoped
|
|
183
|
-
- See `lib/plugin.js` for implementation
|
|
184
|
-
|
|
185
|
-
## TypeScript Integration
|
|
186
|
-
|
|
187
|
-
- TypeScript definitions are in `fastify.d.ts` and `types/`
|
|
188
|
-
- Types must be tested with `tsd`
|
|
189
|
-
- Run `npm run test:typescript` to verify types
|
|
190
|
-
- Keep types in sync with JavaScript implementation
|
|
191
|
-
|
|
192
|
-
## Performance Considerations
|
|
193
|
-
|
|
194
|
-
Fastify prioritizes performance:
|
|
195
|
-
- **Routes**: Pre-compiled functions for fast matching
|
|
196
|
-
- **Validation**: Compiled JSON Schema validators
|
|
197
|
-
- **Serialization**: Compiled serializers (fast-json-stringify)
|
|
198
|
-
- **Logging**: Low-overhead Pino logger
|
|
199
|
-
- **Caching**: Route context caching with `toad-cache`
|
|
200
|
-
|
|
201
|
-
When making changes:
|
|
202
|
-
- Profile performance impact for hot paths
|
|
203
|
-
- Use benchmarks in `examples/benchmark/`
|
|
204
|
-
- Run `npm run benchmark` to measure
|
|
205
|
-
|
|
206
|
-
## Documentation Updates
|
|
207
|
-
|
|
208
|
-
Documentation is critical for Fastify. When changing behavior:
|
|
209
|
-
|
|
210
|
-
1. Update relevant docs in `docs/Reference/` for API changes
|
|
211
|
-
2. Update `docs/Guides/` for usage pattern changes
|
|
212
|
-
3. Check for broken links (CI validates this)
|
|
213
|
-
4. Update examples in `examples/` if needed
|
|
214
|
-
5. Run `npm run lint:markdown` to check docs
|
|
215
|
-
|
|
216
|
-
## Pre-commit Checks
|
|
217
|
-
|
|
218
|
-
Before submitting changes, ensure:
|
|
219
|
-
|
|
220
|
-
1. ✅ All tests pass: `npm test`
|
|
221
|
-
2. ✅ 100% coverage: `npm run coverage`
|
|
222
|
-
3. ✅ Linting passes: `npm run lint`
|
|
223
|
-
4. ✅ TypeScript types pass: `npm run test:typescript`
|
|
224
|
-
5. ✅ Markdown linting passes: `npm run lint:markdown`
|
|
225
|
-
6. ✅ Documentation is updated
|
|
226
|
-
7. ✅ Examples still work if affected
|
|
227
|
-
|
|
228
|
-
## Working with CI
|
|
229
|
-
|
|
230
|
-
Fastify uses GitHub Actions for CI. Workflows are in `.github/workflows/`:
|
|
231
|
-
- **`ci.yml`** - Main CI pipeline
|
|
232
|
-
- **`package-manager-ci.yml`** - Tests multiple package managers
|
|
233
|
-
- **`website.yml`** - Website deployment
|
|
234
|
-
|
|
235
|
-
## Agent-Specific Tips
|
|
236
|
-
|
|
237
|
-
### When Generating Code
|
|
238
|
-
1. Check existing patterns in `lib/` before creating new patterns
|
|
239
|
-
2. Follow the established error handling patterns
|
|
240
|
-
3. Use async/await consistently
|
|
241
|
-
4. Add appropriate hooks if extending lifecycle
|
|
242
|
-
5. Consider TypeScript types from the start
|
|
243
|
-
|
|
244
|
-
### When Refactoring
|
|
245
|
-
1. Ensure all tests still pass
|
|
246
|
-
2. Don't change public APIs without semver consideration
|
|
247
|
-
3. Update TypeScript definitions if signatures change
|
|
248
|
-
4. Check for deprecation needs
|
|
249
|
-
5. Update documentation for changed behavior
|
|
250
|
-
|
|
251
|
-
### When Analyzing Issues
|
|
252
|
-
1. Check `test/` for usage examples
|
|
253
|
-
2. Review relevant `docs/Reference/` files
|
|
254
|
-
3. Look at similar implementations in `lib/`
|
|
255
|
-
4. Consider the plugin system and encapsulation
|
|
256
|
-
5. Check hook timing and order
|
|
257
|
-
|
|
258
|
-
### Common Gotchas
|
|
259
|
-
- **Encapsulation**: Plugins are isolated - decorators don't leak
|
|
260
|
-
- **Hook order**: Hooks run in specific order (see docs/Reference/Hooks.md)
|
|
261
|
-
- **Async boot**: Server starts asynchronously - use `ready()` or `after()`
|
|
262
|
-
- **Error handling**: Use Fastify error classes from `@fastify/error`
|
|
263
|
-
- **Validation**: Schemas are compiled - changes require recompilation
|
|
264
|
-
|
|
265
|
-
## Key Dependencies
|
|
266
|
-
|
|
267
|
-
- **`avvio`** - Plugin loading and boot
|
|
268
|
-
- **`find-my-way`** - Fast HTTP router
|
|
269
|
-
- **`fast-json-stringify`** - Response serialization
|
|
270
|
-
- **`pino`** - Logging
|
|
271
|
-
- **`@fastify/ajv-compiler`** - JSON Schema validation
|
|
272
|
-
- **`light-my-request`** - HTTP injection for testing
|
|
273
|
-
|
|
274
|
-
## Contact and Resources
|
|
275
|
-
|
|
276
|
-
- **Documentation**: https://fastify.dev/
|
|
277
|
-
- **Discord**: https://discord.gg/fastify
|
|
278
|
-
- **GitHub Issues**: https://github.com/fastify/fastify/issues
|
|
279
|
-
- **GitHub Discussions**: https://github.com/fastify/fastify/discussions
|
|
280
|
-
- **Help**: https://github.com/fastify/help
|
|
281
|
-
|
|
282
|
-
## Version Information
|
|
283
|
-
|
|
284
|
-
- **Main branch**: Fastify v5
|
|
285
|
-
- **v4 branch**: https://github.com/fastify/fastify/tree/4.x
|
|
286
|
-
- **LTS Policy**: See `docs/Reference/LTS.md`
|
|
287
|
-
|
|
288
|
-
---
|
|
289
|
-
|
|
290
|
-
This document is maintained by the Fastify team. For questions or suggestions, please open an issue or discussion.
|