V4 迁移指南
本指南旨在帮助您从 Fastify v3 迁移到 v4。
在迁移到 v4 之前,请确保您已修复 v3 中的所有弃用警告。所有 v3 弃用功能已移除,升级后将不再可用。
代码修改器
Fastify v4 代码修改器
为了帮助您进行升级,我们与 Codemod 团队合作,发布了代码修改器,这些修改器将自动更新您的代码以适应 Fastify v4 中的许多新 API 和模式。
运行以下 迁移方案 以自动将您的代码更新到 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 的通用错误处理程序。此错误处理程序将使用 Error 对象中的标头和状态代码(如果存在)。**如果提供了自定义错误处理程序,则不会自动设置标头和状态代码。**
已移除 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
属性访问底层 Request 对象,现在需要使用 reply.raw
。
注意:代码修改器将
reply.res
修改为reply.raw
使用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') });重构为:
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(...)
例如,重构以下代码:
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();
});
注意:代码修改器将 'await register(...)' 修改为
npx codemod@latest fastify/4/await-register-calls
可选 URL 参数
如果您已使用任何隐式可选参数,则在尝试访问路由时将收到 404 错误。现在,您需要显式声明可选参数。
例如,如果您对列出和显示帖子使用相同的路由,请重构以下代码:
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 })
多类型模式的更改
Ajv 已在 Fastify v4 中升级到 v8,这意味着除“null”之外,具有多种类型的“type”关键字 现在被禁止。
您可能会遇到如下控制台警告:
strict mode: use allowUnionTypes to allow union type keyword at "#/properties/image" (strictTypes)
因此,如下所示的模式需要从
{
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 响应标头。