V4 迁移指南
本指南旨在帮助从 Fastify v3 迁移到 v4。
在迁移到 v4 之前,请确保已修复所有来自 v3 的弃用警告。v3 中的所有弃用警告已被删除,升级后将不再工作。
代码转换工具
Fastify v4 代码转换工具
为了帮助您进行升级,我们与 Codemod 团队合作发布了代码转换工具,这些工具可以自动更新您的代码以适应 Fastify v4 中的许多新 API 和模式。
运行以下迁移配方 migration recipe 来自动将您的代码更新为 Fastify v4:
npx codemod@latest fastify/4/migration-recipe
这将执行以下代码转换工具:
fastify/4/remove-app-use
fastify/4/reply-raw-access
fastify/4/wrap-routes-plugin
fastify/4/await-register-calls
每个这些代码转换工具都会自动化 v4 迁移指南中列出的更改。有关可用的 Fastify 代码转换工具和更多详细信息,请参阅 Codemod 注册表 。
重大变更
错误处理组合 (#3261 )
当在异步错误处理函数中抛出一个错误时,如果设置了上一级的错误处理器,则会执行该处理器。如果没有设置上一级的错误处理器,默认的错误处理器将被执行:
import Fastify from 'fastify'
const fastify = Fastify()
fastify.register(async fastify => {
fastify.setErrorHandler(async err => {
console.log(err.message) // 'kaboom'
throw new Error('caught')
})
fastify.get('/encapsulated', async () => {
throw new Error('kaboom')
})
})
fastify.setErrorHandler(async err => {
console.log(err.message) // 'caught'
throw new Error('wrapped')
})
const res = await fastify.inject('/encapsulated')
console.log(res.json().message) // 'wrapped'
根级别的错误处理器是 Fastify 的通用错误处理器。 如果错误对象中存在头部信息和状态码,该错误处理器将使用这些信息。如果提供了自定义的错误处理器,则不会自动设置头部信息和状态码。
移除 app.use()
(#3506 )
在 Fastify v4 中,app.use()
已被移除,并且中间件的使用不再受支持。
如果你需要使用中间件,请使用
@fastify/middie
或
@fastify/express
,这些库将继续得到维护。
然而,强烈建议你迁移到 Fastify 的 钩子。
注意:使用以下命令移除
app.use()
:npx codemod@latest fastify/4/remove-app-use
### 将 `reply.res` 移动到 `reply.raw`
如果你之前使用 `reply.res` 属性来访问底层的请求对象,现在需要使用 `reply.raw`。
> **注意**:将 `reply.res` 替换为 `reply.raw`:
>
> ```bash
> npx codemod@latest fastify/4/reply-raw-access
>
需要 return reply
以指示 Promise 链的“分支”
在某些情况下,例如当响应异步发送或您没有显式返回响应时,现在需要从路由处理程序中返回 reply
参数。
exposeHeadRoutes
默认为 true
从 v4 版本开始,默认情况下每个 GET
路由都会创建一个同名的 HEAD
路由。可以通过在服务器选项中设置 exposeHeadRoutes: false
来恢复之前的默认行为。
同步路由定义 (#2954 )
为了改进路由定义中的错误报告,现在路由注册是同步的。
因此,如果你在插件中指定了 onRoute
回调钩子,则应该:
-
将你的路由包裹在一个插件里(推荐)
例如,重构以下代码:
fastify.register((instance, opts, done) => { instance.addHook('onRoute', (routeOptions) => { const { path, method } = routeOptions; console.log({ path, method }); done(); }); }); fastify.get('/', (request, reply) => { reply.send('hello') });
改为:
```js
fastify.register((instance, opts, done) => {
instance.addHook('onRoute', (routeOptions) => {
const { path, method } = routeOptions;
console.log({ path, method });
done();
});
});
fastify.register((instance, opts, done) => {
instance.get('/', (request, reply) => { reply.send('hello') });
done();
});
注意:使用以下命令进行代码转换:
npx codemod@latest fastify/4/wrap-routes-plugin
* 使用 `await register(...)`
例如,重构以下代码:
```js
fastify.register((instance, opts, done) => {
instance.addHook('onRoute', (routeOptions) => {
const { path, method } = routeOptions;
console.log({ path, method });
});
done();
});
改为:
await fastify.register((instance, opts, done) => {
instance.addHook('onRoute', (routeOptions) => {
const { path, method } = routeOptions;
console.log({ path, method });
});
done();
});
注意:使用以下命令进行代码转换:
npx codemod@latest fastify/4/await-register-calls
### 可选的URL参数
如果您已经使用了任何隐式可选参数,尝试访问该路由时将收到404错误。现在您需要显式声明这些可选参数。
例如,如果您有一个用于列出和显示帖子的相同路由,请重构以下代码:
```js
fastify.get('/posts/:id', (request, reply) => {
const { id } = request.params;
});
改为如下形式:
fastify.get('/posts/:id?', (request, reply) => {
const { id } = request.params;
});
不破坏性更改
.listen()
可变参数签名弃用
fastify.listen()
方法的 可变参数签名 现已弃用。
在此次发布之前,以下方法调用是有效的:
fastify.listen(8000)
fastify.listen(8000, '127.0.0.1')
fastify.listen(8000, '127.0.0.1', 511)
fastify.listen(8000, (err) => { if (err) throw err })
fastify.listen({ port: 8000 }, (err) => { if (err) throw err })
在 Fastify v4 中,仅以下调用是有效的:
fastify.listen()
fastify.listen({ port: 8000 })
fastify.listen({ port: 8000 }, (err) => { if (err) throw err })
多类型模式的 schema 更改
Fastify v4 升级了 Ajv 到 v8 版本,这意味着 “type” 关键字中除了 “null” 之外的多类型 现在被禁止 。
您可能会遇到类似以下的控制台警告:
严格模式:使用 allowUnionTypes 允许联合类型关键字在 "#/properties/image"(strictTypes)
因此,如下所示的 schema 需要更改为:
{
type: 'object',
properties: {
api_key: { type: 'string' },
image: { type: ['object', 'array'] }
}
}
变为:
{
type: 'object',
properties: {
api_key: { type: 'string' },
image: {
anyOf: [
{ type: 'array' },
{ type: 'object' }
]
}
}
}
添加 reply.trailers
方法(#3794 )
Fastify 现在支持 [HTTP Trailer] 响应头。