跳至主要内容
版本:最新版本 (v5.0.x)

V3 迁移指南

本指南旨在帮助您从 Fastify v2 迁移到 v3。

在开始之前,请确保已修复 v2 中的所有弃用警告。所有 v2 弃用功能已移除,升级后将不再起作用。(#1750

重大更改

更改中间件支持 (#2014)

从 Fastify v3 开始,框架本身不再自带中间件支持。

如果您在应用程序中使用 Express 中间件,请在执行此操作之前安装并注册 @fastify/express@fastify/middie 插件。

v2

// Using the Express `cors` middleware in Fastify v2.
fastify.use(require('cors')());

v3

// Using the Express `cors` middleware in Fastify v3.
await fastify.register(require('@fastify/express'));
fastify.use(require('cors')());

更改日志序列化 (#2017)

日志 序列化程序 已更新,现在使用 Fastify RequestReply 对象,而不是原生对象。

如果自定义序列化程序依赖于原生对象上存在但在 Fastify 对象上不存在的 requestreply 属性,则必须更新这些序列化程序。

v2

const fastify = require('fastify')({
logger: {
serializers: {
res(res) {
return {
statusCode: res.statusCode,
customProp: res.customProp
};
}
}
}
});

v3

const fastify = require('fastify')({
logger: {
serializers: {
res(reply) {
return {
statusCode: reply.statusCode, // No change required
customProp: reply.raw.customProp // Log custom property from res object
};
}
}
}
});

更改模式替换 (#2023)

非标准的 replace-way 共享模式支持已被移除。此功能已被符合 JSON Schema 规范的基于 $ref 的替换功能取代。要了解此更改,请阅读 Fastify v3 中的验证和序列化

v2

const schema = {
body: 'schemaId#'
};
fastify.route({ method, url, schema, handler });

v3

const schema = {
body: {
$ref: 'schemaId#'
}
};
fastify.route({ method, url, schema, handler });

更改模式验证选项 (#2023)

setSchemaCompilersetSchemaResolver 选项已被 setValidatorCompiler 选项取代,以实现未来的工具改进。要了解此更改,请阅读 Fastify v3 中的验证和序列化

v2

const fastify = Fastify();
const ajv = new AJV();
ajv.addSchema(schemaA);
ajv.addSchema(schemaB);

fastify.setSchemaCompiler(schema => ajv.compile(schema));
fastify.setSchemaResolver(ref => ajv.getSchema(ref).schema);

v3

const fastify = Fastify();
const ajv = new AJV();
ajv.addSchema(schemaA);
ajv.addSchema(schemaB);

fastify.setValidatorCompiler(({ schema, method, url, httpPart }) =>
ajv.compile(schema)
);

更改预解析钩子行为 (#2286)

从 Fastify v3 开始,preParsing 钩子的行为将略有更改,以支持请求有效负载操作。

该钩子现在接受一个额外的参数 payload,因此新的钩子签名为 fn(request, reply, payload, done)async fn(request, reply, payload)

钩子可以通过 done(null, stream) 返回一个新的流,或者在异步函数的情况下返回流。

如果钩子返回一个新的流,则后续钩子将使用该流而不是原始流。此功能的一个示例用例是处理压缩请求。

新流应向流添加 receivedEncodedLength 属性,该属性应反映从客户端接收的实际数据大小。例如,在压缩请求中,它应该是压缩有效负载的大小。此属性可以在(并且应该)在 data 事件期间动态更新。

不带有效负载的 Fastify v2 旧语法仍然受支持,但已弃用。

更改钩子行为 (#2004)

从 Fastify v3 开始,onRouteonRegister 钩子的行为将略有更改,以支持钩子封装。

  • onRoute - 该钩子将异步调用。在同一封装范围内注册新插件时,该钩子将被继承。因此,此钩子应在注册任何插件之前注册。
  • onRegister - 与 onRoute 钩子相同。唯一的区别是,现在第一次调用不再是框架本身,而是第一个注册的插件。

更改内容类型解析器语法 (#2286)

在 Fastify v3 中,内容类型解析器现在对解析器具有单个签名。

新的签名为 fn(request, payload, done)async fn(request, payload)。请注意,request 现在是 Fastify 请求,而不是 IncomingMessage。有效负载默认情况下为流。如果在 addContentTypeParser 中使用了 parseAs 选项,则 payload 反映选项值(字符串或缓冲区)。

旧签名 fn(req, [done])fn(req, payload, [done])(其中 reqIncomingMessage)仍然受支持,但已弃用。

更改 TypeScript 支持

Fastify 版本 3 中更改了类型系统。新的类型系统引入了泛型约束和默认值,以及定义模式类型(如请求正文、查询字符串等)的新方法!

v2

interface PingQuerystring {
foo?: number;
}

interface PingParams {
bar?: string;
}

interface PingHeaders {
a?: string;
}

interface PingBody {
baz?: string;
}

server.get<PingQuerystring, PingParams, PingHeaders, PingBody>(
'/ping/:bar',
opts,
(request, reply) => {
console.log(request.query); // This is of type `PingQuerystring`
console.log(request.params); // This is of type `PingParams`
console.log(request.headers); // This is of type `PingHeaders`
console.log(request.body); // This is of type `PingBody`
}
);

v3

server.get<{
Querystring: PingQuerystring;
Params: PingParams;
Headers: PingHeaders;
Body: PingBody;
}>('/ping/:bar', opts, async (request, reply) => {
console.log(request.query); // This is of type `PingQuerystring`
console.log(request.params); // This is of type `PingParams`
console.log(request.headers); // This is of type `PingHeaders`
console.log(request.body); // This is of type `PingBody`
});

管理未捕获异常 (#2073)

在同步路由处理程序中,如果抛出错误,服务器会根据设计崩溃,而不会调用已配置的 .setErrorHandler()。这种情况已更改,现在所有同步和异步路由中的意外错误都将得到管理。

v2

fastify.setErrorHandler((error, request, reply) => {
// this is NOT called
reply.send(error)
})
fastify.get('/', (request, reply) => {
const maybeAnArray = request.body.something ? [] : 'I am a string'
maybeAnArray.substr() // Thrown: [].substr is not a function and crash the server
})

v3

fastify.setErrorHandler((error, request, reply) => {
// this IS called
reply.send(error)
})
fastify.get('/', (request, reply) => {
const maybeAnArray = request.body.something ? [] : 'I am a string'
maybeAnArray.substr() // Thrown: [].substr is not a function, but it is handled
})

其他新增功能和改进