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 的通用錯誤處理常式。如果錯誤物件中存在標頭和狀態碼,此錯誤處理常式將會使用它們。**如果提供了自訂錯誤處理常式,則不會自動設定標頭和狀態碼**。
移除 app.use()
(#3506)
在 Fastify v4 中,app.use()
已被移除,不再支援使用中介軟體。
如果您需要使用中介軟體,請使用 @fastify/middie
或 @fastify/express
,它們將會繼續維護。但是,強烈建議您遷移至 Fastify 的 鉤子。
注意:程式碼轉換器會移除帶有
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 })
多種類型架構的變更
在 Fastify v4 中,Ajv 已升級至 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 回應標頭。