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

TypeScript

TypeScript

Fastify 框架是用原生 JavaScript 撰寫的,因此類型定義並不容易維護;然而,自從第 2 版以後,維護者和貢獻者都投入了大量的精力來改進類型。

類型系統在 Fastify 第 3 版中進行了更改。新的類型系統引入了泛型約束和預設值,以及定義 schema 類型的新方法,例如請求主體、查詢字串等等!由於團隊致力於改進框架和類型定義的協同作用,有時 API 的某些部分將不會被輸入類型,或者可能被錯誤地輸入。我們鼓勵您貢獻以幫助我們填補空白。只需確保在開始之前閱讀我們的 CONTRIBUTING.md 文件,以確保一切順利!

本節中的文件涵蓋 Fastify 3.x 版的類型。

插件可能包含或不包含類型。有關更多資訊,請參閱插件。我們鼓勵使用者發送 pull request 以改進類型支援。

🚨 別忘了安裝 @types/node

從範例中學習

學習 Fastify 類型系統的最佳方式是透過範例!以下四個範例應涵蓋最常見的 Fastify 開發案例。在範例之後,還有關於類型系統的更詳細文件。

開始使用

此範例將讓您開始使用 Fastify 和 TypeScript。它會產生一個空白的 http Fastify 伺服器。

  1. 建立一個新的 npm 專案,安裝 Fastify,並安裝 typescript 和 Node.js 類型作為對等相依性

    npm init -y
    npm i fastify
    npm i -D typescript @types/node
  2. 將以下行添加到 package.json"scripts" 部分

    {
    "scripts": {
    "build": "tsc -p tsconfig.json",
    "start": "node index.js"
    }
    }
  3. 初始化一個 TypeScript 設定檔

    npx tsc --init

    或使用推薦的其中一個設定檔

注意:在 tsconfig.json 中將 target 屬性設定為 es2017 或更高版本,以避免 FastifyDeprecation 警告。

  1. 建立一個 index.ts 檔案 - 這將包含伺服器程式碼

  2. 將以下程式碼區塊新增到您的檔案中

    import fastify from 'fastify'

    const server = fastify()

    server.get('/ping', async (request, reply) => {
    return 'pong\n'
    })

    server.listen({ port: 8080 }, (err, address) => {
    if (err) {
    console.error(err)
    process.exit(1)
    }
    console.log(`Server listening at ${address}`)
    })
  3. 執行 npm run build - 這會將 index.ts 編譯成 index.js,可以使用 Node.js 執行。如果您遇到任何錯誤,請在 fastify/help 中開啟一個 issue

  4. 執行 npm run start 以執行 Fastify 伺服器

  5. 您應該會在主控台中看到 Server listening at http://127.0.0.1:8080

  6. 使用 curl localhost:8080/ping 嘗試您的伺服器,它應該會傳回 pong 🏓

🎉 您現在擁有一個運作正常的 Typescript Fastify 伺服器!此範例示範了 3.x 版類型系統的簡潔性。預設情況下,類型系統假設您正在使用 http 伺服器。稍後的範例將示範如何建立更複雜的伺服器,例如 httpshttp2、如何指定路由 schema 等等!

有關使用 TypeScript 初始化 Fastify 的更多範例 (例如啟用 HTTP2),請查看此處的詳細 API 區段 這裡

使用泛型

類型系統嚴重依賴泛型屬性來提供最準確的開發體驗。雖然有些人可能會覺得額外負擔有點麻煩,但這種權衡是值得的!此範例將深入探討如何為路由 schema 和位於路由層級 request 物件上的動態屬性實作泛型類型。

  1. 如果您沒有完成先前的範例,請按照步驟 1-4 進行設定。

  2. index.ts 內,定義三個介面 IQuerystringIHeadersIReply

    interface IQuerystring {
    username: string;
    password: string;
    }

    interface IHeaders {
    'h-Custom': string;
    }

    interface IReply {
    200: { success: boolean };
    302: { url: string };
    '4xx': { error: string };
    }
  3. 使用這三個介面,定義一個新的 API 路由並將它們作為泛型傳遞。速記路由方法 (即 .get) 接受一個泛型物件 RouteGenericInterface,其中包含五個命名屬性:BodyQuerystringParamsHeadersReply。介面 BodyQuerystringParamsHeaders 將透過路由方法傳遞到路由方法處理常式 request 實例中,而 Reply 介面傳遞到 reply 實例中。

    server.get<{
    Querystring: IQuerystring,
    Headers: IHeaders,
    Reply: IReply
    }>('/auth', async (request, reply) => {
    const { username, password } = request.query
    const customerHeader = request.headers['h-Custom']
    // do something with request data

    // chaining .statusCode/.code calls with .send allows type narrowing. For example:
    // this works
    reply.code(200).send({ success: true });
    // but this gives a type error
    reply.code(200).send('uh-oh');
    // it even works for wildcards
    reply.code(404).send({ error: 'Not found' });
    return `logged in!`
    })
  4. 使用 npm run buildnpm run start 建置並執行伺服器程式碼

  5. 查詢 API

    curl localhost:8080/auth?username=admin&password=Password123!

    它應該會傳回 logged in!

  6. 但等等,還有更多!泛型介面也可用於路由層級 hook 方法內。透過新增 preValidation hook 來修改先前的路由

    server.get<{
    Querystring: IQuerystring,
    Headers: IHeaders,
    Reply: IReply
    }>('/auth', {
    preValidation: (request, reply, done) => {
    const { username, password } = request.query
    done(username !== 'admin' ? new Error('Must be admin') : undefined) // only validate `admin` account
    }
    }, async (request, reply) => {
    const customerHeader = request.headers['h-Custom']
    // do something with request data
    return `logged in!`
    })
  7. 建置並執行,並使用設定為非 admin 的任何值的 username 查詢字串選項進行查詢。API 現在應傳回 HTTP 500 錯誤 {"statusCode":500,"error":"Internal Server Error","message":"Must be admin"}

🎉 做得好,現在您可以為每個路由定義介面,並擁有嚴格輸入類型的請求和回覆實例。Fastify 類型系統的其他部分依賴泛型屬性。請務必參考下方詳細的類型系統文件,以了解更多可用資訊。

JSON Schema

為了驗證您的請求和回應,您可以使用 JSON Schema 檔案。如果您還不知道,為您的 Fastify 路由定義 schema 可以增加其吞吐量!請查看驗證和序列化文件以取得更多資訊。

它還具有在您的處理常式 (包括預先驗證等) 中使用已定義類型的優點。

以下是一些關於如何實現這一點的選項。

Fastify 類型提供器

Fastify 提供兩個封裝 json-schema-to-tstypebox 的套件

以及由第三方提供的 zod 包裝器,稱為 fastify-type-provider-zod

它們簡化了 schema 驗證設定,您可以在類型提供器頁面中閱讀有關它們的更多資訊。

以下是如何在使用或不使用類型提供器的情況下,使用 typeboxjson-schema-to-typescriptjson-schema-to-ts 套件設定 schema 驗證的方法。

TypeBox

一個用於一次建置類型和 schema 的有用程式庫是 TypeBox。使用 TypeBox,您可以在程式碼內定義 schema,並根據需要直接將它們用作類型或 schema。

當您想要將其用於驗證 fastify 路由中的某些 payload 時,您可以按如下方式進行

  1. 在您的專案中安裝 typebox

    npm i @sinclair/typebox
  2. 使用 Type 定義您需要的 schema,並使用 Static 建立各自的類型。

    import { Static, Type } from '@sinclair/typebox'

    export const User = Type.Object({
    name: Type.String(),
    mail: Type.Optional(Type.String({ format: 'email' })),
    })

    export type UserType = Static<typeof User>
  3. 在定義路由時,使用定義的類型和 schema

    import Fastify from 'fastify'
    // ...

    const fastify = Fastify()

    fastify.post<{ Body: UserType, Reply: UserType }>(
    '/',
    {
    schema: {
    body: User,
    response: {
    200: User
    },
    },
    },
    (request, reply) => {
    // The `name` and `mail` types are automatically inferred
    const { name, mail } = request.body;
    reply.status(200).send({ name, mail });
    }
    )

json-schema-to-typescript

在上一個範例中,我們使用 Typebox 為我們的路由定義類型和 schema。許多使用者已經在使用 JSON Schema 來定義這些屬性,幸運的是,有一種方法可以將現有的 JSON Schema 轉換為 TypeScript 介面!

  1. 如果您沒有完成「開始使用」範例,請返回並先按照步驟 1-4 進行。

  2. 安裝 json-schema-to-typescript 模組

    npm i -D json-schema-to-typescript
  3. 建立一個名為 schemas 的新資料夾,並新增兩個檔案 headers.jsonquerystring.json。將以下 schema 定義複製並貼到各自的檔案中

    {
    "title": "Headers Schema",
    "type": "object",
    "properties": {
    "h-Custom": { "type": "string" }
    },
    "additionalProperties": false,
    "required": ["h-Custom"]
    }
    {
    "title": "Querystring Schema",
    "type": "object",
    "properties": {
    "username": { "type": "string" },
    "password": { "type": "string" }
    },
    "additionalProperties": false,
    "required": ["username", "password"]
    }
  4. compile-schemas 指令碼新增到 package.json

   {
"scripts": {
"compile-schemas": "json2ts -i schemas -o types"
}
}

json2tsjson-schema-to-typescript 中包含的 CLI 公用程式。schemas 是輸入路徑,而 types 是輸出路徑。5. 執行 npm run compile-schemas。應該會在 types 目錄中建立兩個新檔案。6. 更新 index.ts 以具有以下程式碼

   import fastify from 'fastify'

// import json schemas as normal
import QuerystringSchema from './schemas/querystring.json'
import HeadersSchema from './schemas/headers.json'

// import the generated interfaces
import { QuerystringSchema as QuerystringSchemaInterface } from './types/querystring'
import { HeadersSchema as HeadersSchemaInterface } from './types/headers'

const server = fastify()

server.get<{
Querystring: QuerystringSchemaInterface,
Headers: HeadersSchemaInterface
}>('/auth', {
schema: {
querystring: QuerystringSchema,
headers: HeadersSchema
},
preValidation: (request, reply, done) => {
const { username, password } = request.query
done(username !== 'admin' ? new Error('Must be admin') : undefined)
}
// or if using async
// preValidation: async (request, reply) => {
// const { username, password } = request.query
// if (username !== "admin") throw new Error("Must be admin");
// }
}, async (request, reply) => {
const customerHeader = request.headers['h-Custom']
// do something with request data
return `logged in!`
})

server.route<{
Querystring: QuerystringSchemaInterface,
Headers: HeadersSchemaInterface
}>({
method: 'GET',
url: '/auth2',
schema: {
querystring: QuerystringSchema,
headers: HeadersSchema
},
preHandler: (request, reply, done) => {
const { username, password } = request.query
const customerHeader = request.headers['h-Custom']
done()
},
handler: (request, reply) => {
const { username, password } = request.query
const customerHeader = request.headers['h-Custom']
reply.status(200).send({username});
}
})

server.listen({ port: 8080 }, (err, address) => {
if (err) {
console.error(err)
process.exit(0)
}
console.log(`Server listening at ${address}`)
})

請特別注意此檔案頂部的 import。它可能看起來很多餘,但您需要 import schema 檔案和產生的介面。

做得好!現在您可以同時使用 JSON Schema 和 TypeScript 定義。

json-schema-to-ts

如果您不想從 schema 產生類型,但想要直接從程式碼中使用它們,可以使用套件 json-schema-to-ts

您可以將其安裝為開發相依性。

npm i -D json-schema-to-ts

在您的程式碼中,您可以像一般物件一樣定義您的 schema。但請注意像模組文件中所解釋的那樣使其為 const

const todo = {
type: 'object',
properties: {
name: { type: 'string' },
description: { type: 'string' },
done: { type: 'boolean' },
},
required: ['name'],
} as const; // don't forget to use const !

使用提供的類型 FromSchema,您可以從您的 schema 建構類型並在您的處理常式中使用它。

import { FromSchema } from "json-schema-to-ts";
fastify.post<{ Body: FromSchema<typeof todo> }>(
'/todo',
{
schema: {
body: todo,
response: {
201: {
type: 'string',
},
},
}
},
async (request, reply): Promise<void> => {

/*
request.body has type
{
[x: string]: unknown;
description?: string;
done?: boolean;
name: string;
}
*/

request.body.name // will not throw type error
request.body.notthere // will throw type error

reply.status(201).send();
},
);

外掛程式

Fastify 最顯著的特色之一是其豐富的外掛程式生態系統。外掛程式類型完全支援,並利用宣告合併模式。此範例分為三個部分:建立 TypeScript Fastify 外掛程式、為 Fastify 外掛程式建立類型定義,以及在 TypeScript 專案中使用 Fastify 外掛程式。

建立 TypeScript Fastify 外掛程式

  1. 初始化新的 npm 專案並安裝所需的相依性

    npm init -y
    npm i fastify fastify-plugin
    npm i -D typescript @types/node
  2. build 指令碼新增至 package.json 檔案的 "scripts" 區段,並將 'index.d.ts' 新增至 "types" 區段

    {
    "types": "index.d.ts",
    "scripts": {
    "build": "tsc -p tsconfig.json"
    }
    }
  3. 初始化一個 TypeScript 設定檔

    npx typescript --init

    檔案產生後,在 "compilerOptions" 物件中啟用 "declaration" 選項。

    {
    "compilerOptions": {
    "declaration": true
    }
    }
  4. 建立 index.ts 檔案 - 此檔案將包含外掛程式程式碼

  5. 將下列程式碼新增至 index.ts

    import { FastifyPluginCallback, FastifyPluginAsync } from 'fastify'
    import fp from 'fastify-plugin'

    // using declaration merging, add your plugin props to the appropriate fastify interfaces
    // if prop type is defined here, the value will be typechecked when you call decorate{,Request,Reply}
    declare module 'fastify' {
    interface FastifyRequest {
    myPluginProp: string
    }
    interface FastifyReply {
    myPluginProp: number
    }
    }

    // define options
    export interface MyPluginOptions {
    myPluginOption: string
    }

    // define plugin using callbacks
    const myPluginCallback: FastifyPluginCallback<MyPluginOptions> = (fastify, options, done) => {
    fastify.decorateRequest('myPluginProp', 'super_secret_value')
    fastify.decorateReply('myPluginProp', options.myPluginOption)

    done()
    }

    // define plugin using promises
    const myPluginAsync: FastifyPluginAsync<MyPluginOptions> = async (fastify, options) => {
    fastify.decorateRequest('myPluginProp', 'super_secret_value')
    fastify.decorateReply('myPluginProp', options.myPluginOption)
    }

    // export plugin using fastify-plugin
    export default fp(myPluginCallback, '3.x')
    // or
    // export default fp(myPluginAsync, '3.x')
  6. 執行 npm run build 以編譯外掛程式程式碼,並產生 JavaScript 原始碼檔案和類型定義檔案。

  7. 外掛程式現在已完成,您可以[發佈至 npm]或在本機使用它。

    不需將外掛程式發佈至 npm 才能使用它。您可以將其包含在 Fastify 專案中,並像參考任何程式碼一樣參考它!身為 TypeScript 使用者,請確保宣告覆寫存在於專案編譯會包含的某個位置,以便 TypeScript 解譯器可以處理它。

為 Fastify 外掛程式建立類型定義

此外掛程式指南適用於以 JavaScript 撰寫的 Fastify 外掛程式。此範例中概述的步驟適用於為使用您外掛程式的使用者新增 TypeScript 支援。

  1. 初始化新的 npm 專案並安裝所需的相依性

    npm init -y
    npm i fastify-plugin
  2. 建立兩個檔案 index.jsindex.d.ts

  3. 修改 package json 以將這些檔案包含在 maintypes 屬性下 (名稱不必明確為 index,但建議檔案具有相同的名稱)

    {
    "main": "index.js",
    "types": "index.d.ts"
    }
  4. 開啟 index.js 並新增下列程式碼

    // fastify-plugin is highly recommended for any plugin you write
    const fp = require('fastify-plugin')

    function myPlugin (instance, options, done) {

    // decorate the fastify instance with a custom function called myPluginFunc
    instance.decorate('myPluginFunc', (input) => {
    return input.toUpperCase()
    })

    done()
    }

    module.exports = fp(myPlugin, {
    fastify: '5.x',
    name: 'my-plugin' // this is used by fastify-plugin to derive the property name
    })
  5. 開啟 index.d.ts 並新增下列程式碼

    import { FastifyPluginCallback } from 'fastify'

    interface PluginOptions {
    //...
    }

    // Optionally, you can add any additional exports.
    // Here we are exporting the decorator we added.
    export interface myPluginFunc {
    (input: string): string
    }

    // Most importantly, use declaration merging to add the custom property to the Fastify type system
    declare module 'fastify' {
    interface FastifyInstance {
    myPluginFunc: myPluginFunc
    }
    }

    // fastify-plugin automatically adds named export, so be sure to add also this type
    // the variable name is derived from `options.name` property if `module.exports.myPlugin` is missing
    export const myPlugin: FastifyPluginCallback<PluginOptions>

    // fastify-plugin automatically adds `.default` property to the exported plugin. See the note below
    export default myPlugin

注意fastify-plugin v2.3.0 及更新版本會自動將 .default 屬性和具名匯出新增至匯出的外掛程式。請務必在您的類型中 export defaultexport const myPlugin,以提供最佳的開發人員體驗。如需完整的範例,您可以查看@fastify/swagger

完成這些檔案後,外掛程式現在已準備好供任何 TypeScript 專案使用!

Fastify 外掛程式系統讓開發人員能夠裝飾 Fastify 執行個體以及請求/回覆執行個體。如需更多資訊,請查看這篇關於宣告合併和泛型繼承的網誌文章。

使用外掛程式

在 TypeScript 中使用 Fastify 外掛程式就像在 JavaScript 中使用一樣簡單。使用 import/from 匯入外掛程式,就一切就緒了 -- 但使用者應注意一個例外。

Fastify 外掛程式使用宣告合併來修改現有的 Fastify 類型介面 (如需更多詳細資訊,請查看前兩個範例)。宣告合併並不是很聰明,也就是說,如果外掛程式的類型定義在 TypeScript 解譯器的範圍內,則無論外掛程式是否正在使用,都會包含外掛程式類型。這是使用 TypeScript 的一個不幸限制,而且目前無法避免。

不過,有一些建議可以協助改善這種體驗

{
"rules": {
"@typescript-eslint/no-floating-promises": ["error", {
"allowForKnownSafePromises": [
{ "from": "package", "name": "FastifyInstance", "package": "fastify" },
{ "from": "package", "name": "FastifyReply", "package": "fastify" },
{ "from": "package", "name": "SafePromiseLike", "package": "fastify" },
]
}]
}
}
  • 使用諸如depchecknpm-check 之類的模組來驗證外掛程式相依性是否在您的專案中的某處被使用。

請注意,使用 require 將無法正確載入類型定義,並且可能會導致類型錯誤。TypeScript 只能識別直接匯入程式碼的類型,這表示您可以將 require 與頂端的 import 一起內嵌使用。例如

import 'plugin' // here will trigger the type augmentation.

fastify.register(require('plugin'))
import plugin from 'plugin' //  here will trigger the type augmentation.

fastify.register(plugin)

或甚至在 tsconfig 上明確設定

{
"types": ["plugin"] // we force TypeScript to import the types
}

Vanilla JavaScript 中的程式碼完成

Vanilla JavaScript 可以使用已發佈的類型來提供程式碼完成 (例如Intellisense),方法是遵循TypeScript JSDoc 參考

例如

/**  @type {import('fastify').FastifyPluginAsync<{ optionA: boolean, optionB: string }>} */
module.exports = async function (fastify, { optionA, optionB }) {
fastify.get('/look', () => 'at me');
}

API 類型系統文件

此區段詳細說明 Fastify 3.x 版中可用的所有類型

所有 httphttpshttp2 類型都是從 @types/node 推斷而來

泛型會依其預設值及其限制值記錄。請閱讀這些文章以了解有關 TypeScript 泛型的更多資訊。

如何匯入

Fastify API 由 fastify() 方法提供支援。在 JavaScript 中,您會使用 const fastify = require('fastify') 匯入它。在 TypeScript 中,建議改為使用 import/from 語法,以便解析類型。Fastify 類型系統支援幾種匯入方法。

  1. import fastify from 'fastify'

    • 類型已解析,但無法使用點標記法存取

    • 範例

      import fastify from 'fastify'

      const f = fastify()
      f.listen({ port: 8080 }, () => { console.log('running') })
    • 使用解構來存取類型

      import fastify, { FastifyInstance } from 'fastify'

      const f: FastifyInstance = fastify()
      f.listen({ port: 8080 }, () => { console.log('running') })
    • 解構也適用於主要 API 方法

      import { fastify, FastifyInstance } from 'fastify'

      const f: FastifyInstance = fastify()
      f.listen({ port: 8080 }, () => { console.log('running') })
  2. import * as Fastify from 'fastify'

    • 類型已解析,且可以使用點標記法存取

    • 呼叫主要的 Fastify API 方法需要稍微不同的語法 (請參閱範例)

    • 範例

      import * as Fastify from 'fastify'

      const f: Fastify.FastifyInstance = Fastify.fastify()
      f.listen({ port: 8080 }, () => { console.log('running') })
  3. const fastify = require('fastify')

    • 此語法有效,並且會如預期匯入 fastify;但是,類型將不會解析

    • 範例

      const fastify = require('fastify')

      const f = fastify()
      f.listen({ port: 8080 }, () => { console.log('running') })
    • 支援解構,並且會正確解析類型

      const { fastify } = require('fastify')

      const f = fastify()
      f.listen({ port: 8080 }, () => { console.log('running') })

泛型

許多類型定義共用相同的泛型參數;它們都會在本節中詳細記錄。

大多數定義都取決於 @types/node 模組 httphttpshttp2

RawServer

基礎 Node.js 伺服器類型

預設值:http.Server

限制:http.Serverhttps.Serverhttp2.Http2Serverhttp2.Http2SecureServer

強制執行泛型參數:RawRequestRawReply

RawRequest

基礎 Node.js 請求類型

預設值:RawRequestDefaultExpression

限制:http.IncomingMessagehttp2.Http2ServerRequest

由以下項目強制執行:RawServer

RawReply

基礎 Node.js 回應類型

預設值:RawReplyDefaultExpression

限制:http.ServerResponsehttp2.Http2ServerResponse

由以下項目強制執行:RawServer

Logger

Fastify 記錄公用程式

預設值:FastifyLoggerOptions

由以下項目強制執行:RawServer

RawBody

內容類型剖析器方法的泛型參數。

限制:string | Buffer


Fastify

fastify< RawRequest, RawReply, Logger>(opts?: FastifyServerOptions): FastifyInstance

src

主要的 Fastify API 方法。預設會建立 HTTP 伺服器。利用辨別聯集和多載方法,類型系統會根據傳遞至方法的選項自動推斷正在建立哪種伺服器類型 (http、https 或 http2) (請參閱以下範例以取得更多資訊)。它也支援廣泛的泛型類型系統,讓使用者能夠擴充基礎的 Node.js 伺服器、請求和回覆物件。此外,Logger 泛型可用於自訂記錄類型。請參閱以下範例和泛型分解以取得更多資訊。

範例 1:標準 HTTP 伺服器

不需要指定 Server 泛型,因為類型系統會預設為 HTTP。

import fastify from 'fastify'

const server = fastify()

請參考「從範例學習」 - 入門 範例,以取得更詳細的 HTTP 伺服器逐步說明。

範例 2:HTTPS 伺服器
  1. @types/nodefastify 建立以下導入:
    import fs from 'fs'
    import path from 'path'
    import fastify from 'fastify'
  2. 在設定 Fastify HTTPS 伺服器之前,請執行以下步驟以建立 key.pemcert.pem 檔案:
openssl genrsa -out key.pem
openssl req -new -key key.pem -out csr.pem
openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
rm csr.pem
  1. 實例化 Fastify https 伺服器並新增路由:

    const server = fastify({
    https: {
    key: fs.readFileSync(path.join(__dirname, 'key.pem')),
    cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))
    }
    })

    server.get('/', async function (request, reply) {
    return { hello: 'world' }
    })

    server.listen({ port: 8080 }, (err, address) => {
    if (err) {
    console.error(err)
    process.exit(0)
    }
    console.log(`Server listening at ${address}`)
    })
  2. 建置並執行!使用以下指令查詢以測試您的伺服器:curl -k https://127.0.0.1:8080

範例 3:HTTP2 伺服器

HTTP2 伺服器類型有兩種:不安全和安全。兩者都需要在 options 物件中將 http2 屬性指定為 truehttps 屬性用於建立安全的 HTTP2 伺服器;省略 https 屬性將建立不安全的 HTTP2 伺服器。

const insecureServer = fastify({ http2: true })
const secureServer = fastify({
http2: true,
https: {} // use the `key.pem` and `cert.pem` files from the https section
})

有關使用 HTTP2 的更多詳細資訊,請參閱 Fastify HTTP2 文件頁面。

範例 4:擴充 HTTP 伺服器

您不僅可以指定伺服器類型,還可以指定請求和回應類型。因此,允許您指定特殊的屬性、方法等等!當在伺服器實例化時指定,自訂類型在所有後續的自訂類型實例上都可用。

import fastify from 'fastify'
import http from 'http'

interface customRequest extends http.IncomingMessage {
mySpecialProp: string
}

const server = fastify<http.Server, customRequest>()

server.get('/', async (request, reply) => {
const someValue = request.raw.mySpecialProp // TS knows this is a string, because of the `customRequest` interface
return someValue.toUpperCase()
})
範例 5:指定記錄器類型

Fastify 在底層使用 Pino 記錄程式庫。自 pino@7 起,其所有屬性都可以在建構 Fastify 實例時透過 logger 欄位進行設定。如果您需要的屬性沒有公開,請開啟一個 Issue 給 Pino,或將預先設定的外部 Pino 實例(或任何其他相容的記錄器)作為臨時修復程式透過相同的欄位傳遞給 Fastify。這也允許建立自訂序列化程式,請參閱 記錄 文件以取得更多資訊。

import fastify from 'fastify'

const server = fastify({
logger: {
level: 'info',
redact: ['x-userinfo'],
messageKey: 'message'
}
})

server.get('/', async (request, reply) => {
server.log.info('log message')
return 'another message'
})

fastify.HTTPMethods

src

聯合類型:'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS'

fastify.RawServerBase

src

依賴於 @types/node 模組 httphttpshttp2

聯合類型:http.Server | https.Server | http2.Http2Server | http2.Http2SecureServer

fastify.RawServerDefault

src

依賴於 @types/node 模組 http

http.Server 的類型別名


fastify.FastifyServerOptions< RawServer, Logger>

src

在 Fastify 伺服器實例化中使用的屬性介面。用於主要的 fastify() 方法。RawServerLogger 泛型參數會透過該方法傳遞。

請參閱主要的 fastify 方法類型定義章節,以取得使用 TypeScript 實例化 Fastify 伺服器的範例。

fastify.FastifyInstance< RawServer, RawRequest, RequestGeneric, Logger>

src

表示 Fastify 伺服器物件的介面。這是從 fastify() 方法傳回的伺服器實例。此類型是一個介面,因此如果您的程式碼使用 decorate 方法,則可以透過 宣告合併 進行擴充。

透過使用泛型級聯,附加到實例的所有方法都會繼承實例化的泛型屬性。這表示透過指定伺服器、請求或回應類型,所有方法都會知道如何輸入這些物件。

請參閱主要的 從範例學習 章節以取得詳細指南,或更簡化的 fastify 方法範例,以取得有關此介面的其他詳細資訊。


請求

fastify.FastifyRequest< RequestGeneric, RawServer, RawRequest>

src

此介面包含 Fastify 請求物件的屬性。此處新增的屬性會忽略請求物件的類型(http 或 http2),並忽略它所服務的路由層級;因此,在 GET 請求內部呼叫 request.body 不會擲回錯誤(但祝您好運傳送具有主體的 GET 請求 😉)。

如果您需要在 FastifyRequest 物件中新增自訂屬性(例如,當使用[decorateRequest][DecorateRequest]方法時),您需要在這個介面上使用宣告合併。

FastifyRequest 章節中提供了一個基本範例。如需更詳細的範例,請參閱「從範例學習」章節:外掛程式

範例
import fastify from 'fastify'

const server = fastify()

server.decorateRequest('someProp', 'hello!')

server.get('/', async (request, reply) => {
const { someProp } = request // need to use declaration merging to add this prop to the request interface
return someProp
})

// this declaration must be in scope of the typescript interpreter to work
declare module 'fastify' {
interface FastifyRequest { // you must reference the interface and not the type
someProp: string
}
}

// Or you can type your request using
type CustomRequest = FastifyRequest<{
Body: { test: boolean };
}>

server.get('/typedRequest', async (request: CustomRequest, reply: FastifyReply) => {
return request.body.test
})
fastify.RequestGenericInterface

src

Fastify 請求物件有四個動態屬性:bodyparamsqueryheaders。它們各自的類型可透過此介面指定。它是一個具名屬性介面,使開發人員可以忽略他們不想指定的屬性。所有省略的屬性都會預設為 unknown。對應的屬性名稱為:BodyQuerystringParamsHeaders

import fastify, { RequestGenericInterface } from 'fastify'

const server = fastify()

interface requestGeneric extends RequestGenericInterface {
Querystring: {
name: string
}
}

server.get<requestGeneric>('/', async (request, reply) => {
const { name } = request.query // the name prop now exists on the query prop
return name.toUpperCase()
})

如果您想查看使用此介面的詳細範例,請參閱「從範例學習」章節:JSON 結構描述

fastify.RawRequestDefaultExpression\<RawServer>

src

依賴於 @types/node 模組 httphttpshttp2

泛型參數 RawServer 預設為 RawServerDefault

如果 RawServer 的類型為 http.Serverhttps.Server,則此運算式會傳回 http.IncomingMessage,否則,它會傳回 http2.Http2ServerRequest

import http from 'http'
import http2 from 'http2'
import { RawRequestDefaultExpression } from 'fastify'

RawRequestDefaultExpression<http.Server> // -> http.IncomingMessage
RawRequestDefaultExpression<http2.Http2Server> // -> http2.Http2ServerRequest

回應

fastify.FastifyReply<RequestGeneric, RawServer, RawRequest, RawReply, ContextConfig>

src

此介面包含 Fastify 新增至標準 Node.js 回應物件的自訂屬性。此處新增的屬性會忽略回應物件的類型(http 或 http2)。

如果您需要在 FastifyReply 物件中新增自訂屬性(例如,當使用 decorateReply 方法時),您需要在這個介面上使用宣告合併。

FastifyReply 章節中提供了一個基本範例。如需更詳細的範例,請參閱「從範例學習」章節:外掛程式

範例
import fastify from 'fastify'

const server = fastify()

server.decorateReply('someProp', 'world')

server.get('/', async (request, reply) => {
const { someProp } = reply // need to use declaration merging to add this prop to the reply interface
return someProp
})

// this declaration must be in scope of the typescript interpreter to work
declare module 'fastify' {
interface FastifyReply { // you must reference the interface and not the type
someProp: string
}
}
fastify.RawReplyDefaultExpression< RawServer>

src

依賴於 @types/node 模組 httphttpshttp2

泛型參數 RawServer 預設為 RawServerDefault

如果 RawServer 的類型為 http.Serverhttps.Server,則此運算式會傳回 http.ServerResponse,否則,它會傳回 http2.Http2ServerResponse

import http from 'http'
import http2 from 'http2'
import { RawReplyDefaultExpression } from 'fastify'

RawReplyDefaultExpression<http.Server> // -> http.ServerResponse
RawReplyDefaultExpression<http2.Http2Server> // -> http2.Http2ServerResponse

外掛程式

Fastify 允許使用者使用外掛程式來擴充其功能。外掛程式可以是一組路由、一個伺服器裝飾器或任何其他內容。若要啟動外掛程式,請使用 fastify.register() 方法。

為 Fastify 建立外掛程式時,建議使用 fastify-plugin 模組。此外,「從範例學習」 - 外掛程式 章節中也提供了一個使用 TypeScript 和 Fastify 建立外掛程式的指南。

fastify.FastifyPluginCallback< Options>

src

fastify.register() 方法中使用的介面方法定義。

fastify.FastifyPluginAsync< Options>

src

fastify.register() 方法中使用的介面方法定義。

fastify.FastifyPlugin< Options>

src

fastify.register() 方法中使用的介面方法定義。由於一般的 FastifyPlugin 無法正確推斷異步函式的類型,因此此文件已棄用,建議改用 FastifyPluginCallbackFastifyPluginAsync

fastify.FastifyPluginOptions

src

一個鬆散類型的物件,用於將 fastify.register()options 參數約束為物件。在建立外掛程式時,將其選項定義為此介面的擴展(interface MyPluginOptions extends FastifyPluginOptions),以便將它們傳遞給 register 方法。


Register

fastify.FastifyRegister(plugin: FastifyPluginCallback, opts: FastifyRegisterOptions)

src

fastify.FastifyRegister(plugin: FastifyPluginAsync, opts: FastifyRegisterOptions)

src

fastify.FastifyRegister(plugin: FastifyPlugin, opts: FastifyRegisterOptions)

src

此類型介面指定了 fastify.register() 方法的類型。此類型介面傳回一個具有底層泛型 Options 的函數簽名,其預設值為 FastifyPluginOptions。當呼叫此函數時,它會從 FastifyPlugin 參數推斷此泛型,因此無需指定底層泛型。options 參數是外掛程式選項和兩個額外可選屬性的交集:prefix: stringlogLevelLogLevelFastifyPlugin 已被棄用,請改用 FastifyPluginCallbackFastifyPluginAsync

以下是一個選項推斷的範例

const server = fastify()

const plugin: FastifyPluginCallback<{
option1: string;
option2: boolean;
}> = function (instance, opts, done) { }

server().register(plugin, {}) // Error - options object is missing required properties
server().register(plugin, { option1: '', option2: true }) // OK - options object contains required properties

請參閱「透過範例學習」中的 外掛程式 章節,以取得在 Fastify 中建立 TypeScript 外掛程式的更詳細範例。

fastify.FastifyRegisterOptions

src

此類型是 Options 泛型和一個未導出的介面 RegisterOptions 的交集,該介面指定了兩個可選屬性:prefix: stringlogLevel: LogLevel。此類型也可以指定為一個函式,該函式傳回先前描述的交集。


Logger

請查看 指定記錄器類型 的範例,以取得有關指定自訂記錄器的更多詳細資訊。

fastify.FastifyLoggerOptions< RawServer, RawRequest, RawReply>

src

內部 Fastify 記錄器的介面定義。它模仿了 Pino.js 記錄器。當透過伺服器選項啟用時,請按照一般的 記錄器 文件使用它。

fastify.FastifyLogFn

src

一個重載函數介面,實作 Fastify 呼叫記錄方法的方式。此介面會傳遞到 FastifyLoggerOptions 物件上所有相關的記錄層級屬性。

fastify.LogLevel

src

以下項目的聯集類型:'info' | 'error' | 'debug' | 'fatal' | 'warn' | 'trace'


Context

內容類型定義與類型系統的其他高度動態的部分類似。路由內容在路由處理常式方法中可用。

fastify.FastifyRequestContext

src

一個具有單一必要屬性 config 的介面,其預設設定為 unknown。可以使用泛型或重載來指定。

此類型定義可能不完整。如果您正在使用它,並且可以提供更多關於如何改進定義的詳細資訊,我們強烈建議您在主要的 fastify/fastify 儲存庫中開啟一個問題。預先感謝!

fastify.FastifyReplyContext

src

一個具有單一必要屬性 config 的介面,其預設設定為 unknown。可以使用泛型或重載來指定。

此類型定義可能不完整。如果您正在使用它,並且可以提供更多關於如何改進定義的詳細資訊,我們強烈建議您在主要的 fastify/fastify 儲存庫中開啟一個問題。預先感謝!


Routing

Fastify 的核心原則之一是其路由功能。此章節中定義的大多數類型都由 Fastify 實例的 .route.get/.post/.etc 方法在底層使用。

fastify.RouteHandlerMethod< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>

src

路由處理常式方法的類型宣告。有兩個引數,requestreply,它們分別由 FastifyRequestFastifyReply 類型化。泛型參數會傳遞到這些引數。該方法會傳回 voidPromise<any>,分別用於同步和非同步處理常式。

fastify.RouteOptions< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>

src

一個擴展 RouteShorthandOptions 並新增以下三個必要屬性的介面

  1. method 對應於單一 HTTPMethodHTTPMethods 的清單
  2. url 路由的字串
  3. handler 路由處理常式方法,請參閱[RouteHandlerMethod][]以取得更多詳細資訊
fastify.RouteShorthandMethod< RawServer, RawRequest, RawReply>

src

一個重載的函數介面,用於三種簡寫路由方法,以便與 .get/.post/.etc 方法結合使用。

fastify.RouteShorthandOptions< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>

src

一個涵蓋路由所有基本選項的介面。此介面上的每個屬性都是可選的,並且它是 RouteOptions 和 RouteShorthandOptionsWithHandler 介面的基礎。

fastify.RouteShorthandOptionsWithHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>

src

此介面向 RouteShorthandOptions 介面新增了一個單一必要屬性 handler,其類型為 RouteHandlerMethod


Parsers

RawBody

可以是 stringBuffer 的泛型類型

fastify.FastifyBodyParser< RawBody, RawServer, RawRequest>

src

用於指定主體剖析器方法的函式類型定義。使用 RawBody 泛型來指定要剖析的主體類型。

fastify.FastifyContentTypeParser< RawServer, RawRequest>

src

用於指定主體剖析器方法的函式類型定義。內容會透過 RawRequest 泛型進行類型化。

fastify.AddContentTypeParser< RawServer, RawRequest>

src

addContentTypeParser 方法的過載介面函式定義。如果將 parseAs 傳遞給 opts 參數,則定義會使用[FastifyBodyParser][]作為 parser 參數;否則,它會使用[FastifyContentTypeParser][].

fastify.hasContentTypeParser

src

用於檢查特定內容類型的類型解析器是否存在的方法


錯誤

fastify.FastifyError

src

FastifyError 是一個自訂錯誤物件,包含狀態碼和驗證結果。

它擴展了 Node.js 的 Error 類型,並新增了兩個額外的可選屬性:statusCode: numbervalidation: ValidationResult[]

fastify.ValidationResult

src

路由驗證在內部依賴 Ajv,這是一個高效能的 JSON Schema 驗證器。

此介面會傳遞給 FastifyError 的實例。


Hook

fastify.onRequestHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, done: (err?: FastifyError) => void): Promise<unknown>| void

src

onRequest 是請求生命週期中第一個執行的 Hook。之前沒有 Hook,下一個 Hook 將是 preParsing

注意:在 onRequest Hook 中,request.body 將始終為 null,因為 body 解析發生在 preHandler Hook 之前。

fastify.preParsingHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, done: (err?: FastifyError) => void): Promise<unknown>| void

src

preParsing 是請求生命週期中第二個執行的 Hook。先前的 Hook 是 onRequest,下一個 Hook 將是 preValidation

注意:在 preParsing Hook 中,request.body 將始終為 null,因為 body 解析發生在 preValidation Hook 之前。

注意:您還應該將 receivedEncodedLength 屬性新增至返回的 stream。此屬性用於正確地將請求 payload 與 Content-Length 標頭值相匹配。理想情況下,應該在每個接收到的 chunk 上更新此屬性。

fastify.preValidationHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, done: (err?: FastifyError) => void): Promise<unknown>| void

src

preValidation 是請求生命週期中第三個執行的 Hook。先前的 Hook 是 preParsing,下一個 Hook 將是 preHandler

fastify.preHandlerHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, done: (err?: FastifyError) => void): Promise<unknown>| void

src

preHandler 是請求生命週期中第四個執行的 Hook。先前的 Hook 是 preValidation,下一個 Hook 將是 preSerialization

fastify.preSerializationHookHandler< PreSerializationPayload, RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, payload: PreSerializationPayload, done: (err: FastifyError | null, res?: unknown) => void): Promise<unknown>| void

src

preSerialization 是請求生命週期中第五個執行的 Hook。先前的 Hook 是 preHandler,下一個 Hook 將是 onSend

注意:如果 payload 是字串、Buffer、stream 或 null,則不會呼叫此 Hook。

fastify.onSendHookHandler< OnSendPayload, RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, payload: OnSendPayload, done: (err: FastifyError | null, res?: unknown) => void): Promise<unknown>| void

src

您可以使用 onSend Hook 更改 payload。它是請求生命週期中第六個執行的 Hook。先前的 Hook 是 preSerialization,下一個 Hook 將是 onResponse

注意:如果您更改 payload,則只能將其更改為字串、Buffer、stream 或 null。

fastify.onResponseHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, done: (err?: FastifyError) => void): Promise<unknown>| void

src

onResponse 是請求 Hook 生命週期中的第七個也是最後一個 Hook。先前的 Hook 是 onSend,沒有下一個 Hook。

當已發送回應時,會執行 onResponse Hook,因此您將無法向用戶端發送更多資料。不過,它對於向外部服務發送資料很有用,例如收集統計資料。

fastify.onErrorHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(request: FastifyRequest, reply: FastifyReply, error: FastifyError, done: () => void): Promise<unknown>| void

src

如果您需要執行一些自訂錯誤記錄或在發生錯誤時新增一些特定的標頭,此 Hook 非常有用。

它不適用於變更錯誤,並且呼叫 reply.send 將會擲回例外狀況。

只有在 customErrorHandler 執行之後,且僅當 customErrorHandler 將錯誤發送回使用者時,才會執行此 Hook (請注意,預設的 customErrorHandler 始終將錯誤發送回使用者)。

注意:與其他 Hook 不同,不支援將錯誤傳遞給 done 函式。

fastify.onRouteHookHandler< RawServer, RawRequest, RawReply, RequestGeneric, ContextConfig>(opts: RouteOptions &{path: string; prefix: string }): Promise<unknown>| void

src

在註冊新路由時觸發。接聽程式會將 routeOptions 物件作為唯一參數傳遞。介面是同步的,因此接聽程式不會傳遞回呼

fastify.onRegisterHookHandler< RawServer, RawRequest, RawReply, Logger>(instance: FastifyInstance, done: (err?: FastifyError) => void): Promise<unknown>| void

src

在註冊新外掛程式並建立新的封裝環境時觸發。此 Hook 將在註冊的程式碼之前執行。

如果您正在開發需要知道何時形成外掛程式環境的外掛程式,並且您想要在該特定環境中運作,則此 Hook 非常有用。

注意:如果外掛程式包裝在 fastify-plugin 內,則不會呼叫此 Hook。

fastify.onCloseHookHandler< RawServer, RawRequest, RawReply, Logger>(instance: FastifyInstance, done: (err?: FastifyError) => void): Promise<unknown>| void

src

當調用 fastify.close() 以停止伺服器時觸發。當外掛程式需要「關閉」事件時,例如關閉到資料庫的開啟連線時,此功能非常有用。