跳至主要內容
版本:最新版 (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 結構描述規格的 $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)
);

變更的 preParsing 鉤子行為 (#2286)

從 Fastify v3 開始,preParsing 鉤子的行為會稍微變更,以支援請求負載操作。

鉤子現在會採用額外引數 payload,因此新的鉤子簽章為 fn(request, reply, payload, done)async fn(request, reply, payload)

鉤子可以選擇性地透過 done(null, stream) 或在 async 函式的情況下傳回資料流,來傳回新的資料流。

如果鉤子傳回新的資料流,則後續鉤子將會使用該資料流,而不是原始資料流。此項的範例用例是處理壓縮請求。

新的資料流應該將 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
})

進一步新增和改進