Fastify 中文文档 (latest — v4.23.1)
TypeScript
Fastify 是用普通的 JavaScript 编写的,因此,类型定义的维护并不容易。可喜的是,自版本 2 以来,维护者和贡献者们已经在类型维护上投入了巨大的努力。
版本 3 的类型系统发生了改变。新的系统带来了泛型约束 (generic constraining) 与默认值,以及定义请求 body,querystring 等 schema 的新方式!在团队改善框架和类型定义的协作中,难免有所纰漏。我们鼓励你
参与贡献
。请记得在开始前阅读
CONTRIBUTING.md
一文!
本文档介绍的是 Fastify 3.x 版本的类型
插件不一定包含类型定义。更多内容请看 插件 。我们鼓励用户提交 PR 来改善插件的类型支持。
别忘了安装
@types/node
。
从例子中学习
通过例子来学习 Fastify 的类型系统是最好的途径!以下四个例子涵盖了最常见的开发场景。例子之后是更详尽深入的文档。
起步
这个例子展示了如何使用 Fastify 和 TypeScript 构建一个最简单的 http 服务器。
-
创建一个 npm 项目,安装 Fastify、typescript 和 node.js 的类型文件:
npm init -y npm i fastify npm i -D typescript @types/node
-
在
package.json
的"scripts"
里添加以下内容:{ "scripts": { "build": "tsc -p tsconfig.json", "start": "node index.js"
-
初始化 TypeScript 配置文件:
npx tsc --init
或使用一个 推荐的配置文件 。
-
创建
index.ts
,在此编写服务器的代码。 -
将下列代码添加到该文件中:
import fastify from 'fastify' const server = fastify() server.get('/ping', async (request, reply) => { return 'pong\n' server.listen(8080, (err, address) => { if (err) { console.error(err) process.exit(1) console.log(`Server listening at ${address}`)
-
执行
npm run build
。这么做会将index.ts
编译为能被 Node.js 运行的index.js
。如果遇到了错误,请在 fastify/help 发布 issue。 -
执行
npm run start
来启动 Fastify 服务器。 -
你将看到控制台输出:
Server listening at http://127.0.0.1:8080
。 -
通过
curl localhost:8080/ping
访问服务,你将收到pong
。
🎉 现在,你有了一个能用的 TypeScript 写的 Fastify 服务器!这个例子演示了在 3.x 版本中,类型系统有多么简单。默认情况下,类型系统会假定你使用的是
http
服务器。后续的例子将为你展现更多内容,例如,创建较为复杂的服务器 (
https
与
http2
),以及指定路由的 schema!
更多使用 TypeScript 初始化 Fastify 的示例 (如启用 HTTP2),请在 这里 查阅详细的 API。
使用泛型
类型系统重度依赖于泛型属性来提供最精确的开发时体验。有人可能会认为这么做有些麻烦,但这是值得的!这个例子将展示如何在路由 schema 中实现泛型,以及路由层
request
对象上的动态属性。
-
照着上面例子的 1-4 步来初始化项目。
-
在
index.ts
中定义两个接口 (interface),IQuerystring
和IHeaders
:interface IQuerystring { username: string; password: string; interface IHeaders { 'h-Custom': string;
-
使用这两个接口,定义一个新的 API 路由,并将它们用作泛型。路由方法的简写形式 (如
.get
) 接受一个泛型对象RouteGenericInterface
,它包含了五个具名属性:Body
、Querystring
、Params
、Headers
以及Reply
。Body
、Querystring
、Params
和Headers
四个接口会随着路由方法向下传递,到达路由处理函数中的request
实例,Reply
接口则会到达reply
实例。server.get<{ Querystring: IQuerystring, Headers: IHeaders }>('/auth', async (request, reply) => { const { username, password } = request.query const customerHeader = request.headers['h-Custom'] // 处理请求数据 return `logged in!`
-
执行
npm run build
和npm run start
来构建并运行项目。 -
访问 api:
curl localhost:8080/auth?username=admin&password=Password123!
将会返回
logged in!
。 -
此外,泛型接口还可以用在路由层钩子方法中。在上面的路由内加上一个
preValidation
钩子:server.get<{ Querystring: IQuerystring, Headers: IHeaders }>('/auth', { preValidation: (request, reply, done) => { const { username, password } = request.query done(username !== 'admin' ? new Error('Must be admin') : undefined) // 或使用 async // preValidation: async (request, reply) => { // const { username, password } = request.query // return username !== "admin" ? new Error("Must be admin") : undefined; // } }, async (request, reply) => { const customerHeader = request.headers['h-Custom'] // 处理请求数据 return `logged in!`
-
构建运行之后,使用任何值不为
admin
的username
查询字符串访问服务。你将收到一个 500 错误:{"statusCode":500,"error":"Internal Server Error","message":"Must be admin"}
干得漂亮。现在你能够为每个路由定义接口,并拥有严格类型的请求与响应实例了。Fastify 类型系统的其他部分依赖于泛型属性。关于如何使用它们,请参照后文详细的类型系统文档。
JSON Schema
你可以通过 JSON Schema 来验证请求与响应。给 Fastify 路由定义 schema 还能提高吞吐量!更多信息请见 验证和序列化 。
此外,在路由处理函数 (包括 pre-validation 等钩子) 中使用定义好的类型也是有好处的。
以下列出了几种实现方案。
typebox
typebox 能帮助你同时构建类型与 schema。通过 typebox 在代码里定义好 schema 之后,你便能将其当作类型或 schema 来使用。
在 Fastify 路由中验证 payload,你可以这么做:
-
安装
typebox
。npm i @sinclair/typebox
-
使用
Type
定义 schema,并通过Static
创建相应的类型。import { Static, Type } from '@sinclair/typebox' const User = Type.Object({ name: Type.String(), mail: Type.Optional(Type.String({ format: "email" })), type UserType = Static<typeof User>;
-
在路由中使用定义好的类型与 schema。
const app = fastify(); app.post<{ Body: UserType; Reply: UserType }>( schema: { body: User, response: { 200: User, (req, rep) => { const { body: user } = req; /* user 的类型如下: * const user: StaticProperties<{ * name: TString; * mail: TOptional<TString>; //... rep.status(200).send(user);
Schemas in JSON Files
在上一个例子里,我们使用接口定义了请求 querystring 和 header 的类型。许多用户使用 JSON Schema 来处理这些工作,幸运的是,有一套方法能将现有的 JSON Schema 转换为 TypeScript 接口!
-
完成 '起步' 中例子的 1-4 步。
-
安装
json-schema-to-typescript
模块:npm i -D json-schema-to-typescript
-
新建一个名为
schemas
的文件夹。在其中添加headers.json
与querystring.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"]
-
在 package.json 里加上一行
compile-schemas
脚本:{ "scripts": { "compile-schemas": "json2ts -i schemas -o types"
json2ts
是囊括在json-schema-to-typescript
中的命令行工具。schemas
是输入路径,types
则是输出路径。 -
执行
npm run compile-schemas
,在types
文件夹下生成两个新文件。 -
更新
index.ts
:import fastify from 'fastify' // 导入 json schema import QuerystringSchema from './schemas/querystring.json' import HeadersSchema from './schemas/headers.json' // 导入生成的接口 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) }, async (request, reply) => { const customerHeader = request.headers['h-Custom'] // 处理请求数据 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(8080, (err, address) => { if (err) { console.error(err) process.exit(0) console.log(`Server listening at ${address}`)
要特别关注文件顶部的导入。虽然看上去有些多余,但你必须同时导入 schema 与生成的接口。
真棒!现在你就能同时运用 JSON Schema 与 TypeScript 的定义了。
json-schema-to-ts
不想基于 schema 生成类型,而是直接使用它们的话,你可以考虑 json-schema-to-ts 模块。
安装该模块为 dev-dependency:
npm install -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;
通过类型
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 的类型如下:
[x: string]: unknown;
description?: string;
done?: boolean;
name: string;
request.body.name // 不会抛出类型错误
request.body.notthere // 会抛出类型错误
reply.status(201).send();
插件
拓展性强的插件生态系统是 Fastify 最突出的特性之一。插件完全支持类型系统,并利用了 声明合并 (declaration merging) 模式的优势。下面的例子将分为三个部分:用 TypeScript 编写 Fastify 插件,为插件编写类型定义,以及在 TypeScript 项目中使用插件。
用 TypeScript 编写 Fastify 插件
-
初始化新的 npm 项目,并安装必需的依赖。
npm init -y npm i fastify fastify-plugin npm i -D typescript @types/node
-
在
package.json
的"scripts"
中加上一行build
,"types"
中写入'index.d.ts'
:{ "types": "index.d.ts", "scripts": { "build": "tsc -p tsconfig.json"
-
初始化 TypeScript 配置文件:
npx typescript --init
文件生成后,启用
"compilerOptions"
对象中的"declaration"
选项。{ "compileOptions": { "declaration": true
-
新建
index.ts
文件,在这里编写插件代码。 -
在
index.ts
中写入以下代码。import { FastifyPluginCallback, FastifyPluginAsync } from 'fastify' import fp from 'fastify-plugin' // 利用声明合并,将插件的属性加入合适的 fastify 接口。 declare module 'fastify' { interface FastifyRequest { myPluginProp: string interface FastifyReply { myPluginProp: number // 定义选项 export interface MyPluginOptions { myPluginOption: string // 使用回调函数定义插件 const myPluginCallback: FastifyPluginCallback<MyPluginOptions> = (fastify, options, done) => { fastify.decorateRequest('myPluginProp', 'super_secret_value') fastify.decorateReply('myPluginProp', options.myPluginOption) done() // 使用 promise 定义插件 const myPluginAsync: FastifyPluginAsync<MyPluginOptions> = async (fastify, options) => { fastify.decorateRequest('myPluginProp', 'super_secret_value') fastify.decorateReply('myPluginProp', options.myPluginOption) // 使用 fastify-plugin 导出插件 export default fp(myPluginCallback, '3.x') // 或者 // export default fp(myPluginAsync, '3.x')
-
运行
npm run build
编译,生成 JavaScript 源文件以及类型定义文件。 -
如此一来,插件便完工了。你可以[发布到 npm] 或直接本地使用。
并非将插件发布到 npm 才能 使用。你可以将其放在 Fastify 项目内,并像引用任意代码一样引用它!请确保声明文件在项目编译的范围内,以便能被 TypeScript 处理器使用。
为插件编写类型定义
以下例子是为 JavaScript 编写的 Fastify 插件所作,展示了如何在插件中加入 TypeScript 支持,以方便用户使用。
-
初始化新的 npm 项目,并安装必需的依赖。
npm init -y npm i fastify-plugin
-
新建
index.js
和index.d.ts
。 -
将这两个文件写入 package.json 的
main
和types
中 (文件名不一定为index
,但推荐都使用这个名字):{ "main": "index.js", "types": "index.d.ts"
-
在
index.js
中加入以下代码:// 极力推荐使用 fastify-plugin 包装插件 const fp = require('fastify-plugin') function myPlugin (instance, options, done) { // 用自定义函数 myPluginFunc 装饰 fastify 实例 instance.decorate('myPluginFunc', (input) => { return input.toUpperCase() done() module.exports = fp(myPlugin, { fastify: '3.x', name: 'my-plugin' // 被 fastify-plugin 用来获取属性名
-
在
index.d.ts
中加入以下代码:import { FastifyPlugin } from 'fastify' interface PluginOptions { //... // 你可以导出任意内容 // 在此,我们导出之前添加的装饰器 export interface myPluginFunc { (input: string): string // 利用声明合并将自定义属性加入 Fastify 的类型系统 declare module 'fastify' { interface FastifyInstance { myPluginFunc: myPluginFunc // fastify-plugin 会自动添加具名导出,因此请确保加上该类型。 // 如果缺少 `module.exports.myPlugin`,变量名会通过 `options.name` 属性获取。 export const myPlugin: FastifyPlugin<PluginOptions> // fastify-plugin 会自动在导出的插件上添加 `.default` 属性。详见下文。 export default myPlugin
注意
:v2.3.0 及以上版本的
fastify-plugin
会自动给导出的插件添加
default
属性以及具名导出。为了更好的开发体验,请确保在类型文件中加上了
export default
与
export const myPlugin
。完整的例子可以查看
fastify-swagger
。
这样一来,该插件便能被任意 TypeScript 项目使用了!
Fastify 的插件系统允许开发者装饰 Fastify 以及 request/reply 的实例。更多信息请见 声明合并与泛型继承 一文。
使用插件
在 TypeScript 中使用插件和在 JavaScript 中使用一样简单,只需要用到
import/from
而已,除了一个特殊情况。
Fastify 插件使用声明合并来修改已有的 Fastify 类型接口 (详见上一个例子)。声明合并没有那么 _聪明_,只要插件的类型定义在 TypeScript 解释器的范围内,那么 不管 插件本身是否被使用,这些定义都会被包括。这是 TypeScript 的限制,目前无法规避。
尽管如此,还是有一些建议能帮助改善这种状况:
原生 JavaScript 的代码补全
原生 JavaScript 能根据发布好的类型,依照 TypeScript 的 JSDoc 参考 来完成代码补全 (例如 Intellisense )。
举个例子:
/** @type {import('fastify').FastifyPluginAsync<{ optionA: boolean, optionB: string }>} */
module.exports = async function (fastify, { optionA, optionB }) {
fastify.get('/look', () => 'at me');
API 类型系统文档
本节详述了所有在 Fastify 3.x 版本中可用的类型。
所有
http
、
https
以及
http2
的类型来自
@types/node
。
泛型 的文档包括了其默认值以及约束值。更多关于 TypeScript 泛型的信息请阅读以下文章。
如何导入
Fastify 的 API 都首先来自于
fastify()
方法。在 JavaScript 中,通过
const fastify = require('fastify')
来导入。在 TypeScript 中,建议的做法是使用
import/from
语法,这样类型能得到处理。有如下几种导入的方法。
-
import fastify from 'fastify'
-
类型得到了处理,但无法通过点标记 (dot notation) 访问
-
例子:
import fastify from 'fastify' const f = fastify() f.listen(8080, () => { console.log('running') })
-
通过解构赋值访问类型
import fastify, { FastifyInstance } from 'fastify' const f: FastifyInstance = fastify() f.listen(8080, () => { console.log('running') })
-
主 API 方法也可以使用解构赋值
import { fastify, FastifyInstance } from 'fastify' const f: FastifyInstance = fastify() f.listen(8080, () => { console.log('running') })
-
-
import * as Fastify from 'fastify'
-
类型得到了处理,并可通过点标记访问
-
主 API 方法要用稍微不同的语法调用 (见例子)
-
例子:
import * as Fastify from 'fastify' const f: Fastify.FastifyInstance = Fastify.fastify() f.listen(8080, () => { console.log('running') })
-
-
const fastify = require('fastify')
-
语法有效,也能正确地导入。然而并 不 支持类型
-
例子:
const fastify = require('fastify') const f = fastify() f.listen(8080, () => { console.log('running') })
-
支持解构,且能处理类型
const { fastify } = require('fastify') const f = fastify() f.listen(8080, () => { console.log('running') })
-
泛型
许多类型定义共用了某些泛型参数。它们都在本节有详尽的描述。
多数定义依赖于
@node/types
中的
http
、
https
与
http2
模块。
RawServer
底层 Node.js server 的类型。
默认值:
http.Server
约束值:
http.Server
、
https.Server
、
http2.Http2Server
、
http2.Http2SecureServer
必要的泛型参数 (Enforces generic parameters):
RawRequest
、
RawReply
RawRequest
底层 Node.js request 的类型。
默认值:
RawRequestDefaultExpression
约束值:
http.IncomingMessage
、
http2.Http2ServerRequest
被
RawServer
约束。
RawReply
底层 Node.js response 的类型。
默认值:
RawReplyDefaultExpression
约束值:
http.ServerResponse
、
http2.Http2ServerResponse
被
RawServer
约束。
Logger
Fastify 日志工具。
默认值:
FastifyLoggerOptions
被
RawServer
约束。
RawBody
为 content-type-parser 方法提供的泛型参数。
约束值:
string | Buffer
Fastify
fastify< RawServer , RawRequest , RawReply , Logger >(opts?: FastifyServerOptions ): FastifyInstance
Fastify 首要的 API 方法。默认情况下创建一个 HTTP 服务器。通过可辨识联合 (discriminant unions) 及重载的方法 (overload methods),类型系统能自动地根据传递给该方法的选项 (详见下文例子),推断出服务器的类型 (http、https 或 http2)。同时,可拓展的泛型类型系统允许用户拓展底层的 Node.js Server、Request 和 Reply 对象。此外,自定义日志类型则可以运用
Logger
泛型。详见下文的例子和泛型分类说明。
例子 1:标准的 HTTP 服务器
无需指明
Server
的具体类型,因为默认值就是 HTTP 服务器。
import fastify from 'fastify'
const server = fastify()
回顾“从例子中学习”的 起步 一节的示例来获取更详细的内容。
例子 2:HTTPS 服务器
-
从
@types/node
与fastify
导入模块。import fs from 'fs' import path from 'path' import fastify from 'fastify'
-
按照官方 Node.js https 服务器指南 的步骤,创建
key.pem
与cert.pem
文件。 -
实例化一个 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(8080, (err, address) => { if (err) { console.error(err) process.exit(0) console.log(`Server listening at ${address}`)
-
构建并运行!执行
curl -k https://localhost:8080
来测试服务。
例子 3:HTTP2 服务器
HTTP2 服务器有两种类型,非安全与安全。两种类型都需要在
options
对象中设置
http2
属性的值为
true
。设置
https
属性会创建一个安全的 http2 服务器;忽略该属性则创建非安全的服务器。
const insecureServer = fastify({ http2: true })
const secureServer = fastify({
http2: true,
https: {} // 使用 https 服务的 `key.pem` 和 `cert.pem` 文件
更多细节详见 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 // 由于 `customRequest` 接口的存在,TypeScript 能知道这是一个字符串
return someValue.toUpperCase()
例子 5:指定日志类型
Fastify 使用
Pino
作为日志工具。其中一些属性可以在构建 Fastify 实例时,在
logger
字段中配置。如果需要的属性未被暴露出来,你也能通过将一个外部配置好的 Pino 实例 (或其他兼容的日志工具) 传给这个字段,来配置这些属性。这么做也允许你自定义序列化工具,详见
日志
的文档。
要使用 Pino 的外部实例,请将
@types/pino
添加到 devDependencies 中,并把实例传给
logger
字段:
import fastify from 'fastify'
import pino from 'pino'
const server = fastify({
logger: pino({
level: 'info',
redact: ['x-userinfo'],
messageKey: 'message'
server.get('/', async (request, reply) => {
server.log.info('log message')
return 'another message'
fastify.HTTPMethods
'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS'
的联合类型 (Union type)
fastify.RawServerBase
依赖于
@types/node
的模块
http
、
https
、
http2
http.Server | https.Server | http2.Http2Server | http2.Http2SecureServer
的联合类型
fastify.RawServerDefault
依赖于
@types/node
的模块
http
http.Server
的类型别名
fastify.FastifyServerOptions< RawServer , Logger >
Fastify 服务器实例化时,调用
fastify()
方法使用到的接口。泛型参数
RawServer
和
Logger
会随此方法向下传递。
关于用 TypeScript 实例化一个 Fastify 服务器的例子,请见 fastify 主方法的类型定义。
fastify.FastifyInstance< RawServer , RawRequest , RequestGeneric , Logger >
表示 Fastify 服务器对象的接口,
fastify()
方法的返回值。假如你使用了
decorate
方法,借由
声明合并
可以拓展该接口。
通过泛型级联 (generic cascading),实例上所有的方法都能继承实例化时的泛型属性。这意味着只要指定了服务器、请求或响应的类型,所有方法都能随之确定这些对象的类型。
具体说明请看“ 从例子中学习 ”一节,或 fastify 方法中更简洁的例子。
Request
fastify.FastifyRequest< RequestGeneric , RawServer , RawRequest >
该接口包含了 Fastify 请求对象的属性。这些属性无视请求类型 (http 或 http2),也无关路由层级。因此在 GET 请求中访问
request.body
并不会抛错 (假如 GET 有 body 😉)。
假如你需要为
FastifyRequest
对象添加自定义属性 (例如使用 [
decorateRequest
][DecorateRequest] 方法时),你应该针对该接口应用声明合并。
在
FastifyRequest
里有基本的范例。更详细的例子请见“从例子中学习”的
插件
一节。
例子
import fastify from 'fastify'
const server = fastify()
server.decorateRequest('someProp', 'hello!')
server.get('/', async (request, reply) => {
const { someProp } = request // 需要通过声明合并将该属性添加到 request 接口上
return someProp
// 以下声明必须在 typescript 解释器的作用域内
declare module 'fastify' {
interface FastifyRequest { // 引用的是接口而非类型
someProp: string
// 你也可以如此定义 request 的类型
type CustomRequest = FastifyRequest<{
Body: { test: boolean };
server.get('/typedRequest', async (request: CustomRequest, reply: FastifyReply) => {
return request.body.test
fastify.RequestGenericInterface
Fastify 的请求对象有四个动态属性:
body
、
params
、
query
以及
headers
,它们对应的类型可以通过该接口设定。这是具名属性接口,允许开发者忽略他们不想指定的类型。所有忽略的属性默认为
unknown
。四个属性名为:
Body
、
Querystring
、
Params
和
Headers
。
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 // 此时 query 属性上有了 name
return name.toUpperCase()
在“从例子中学习”的 JSON Schema 一节中,你能找到更具体的范例。
fastify.RawRequestDefaultExpression< RawServer >
依赖于
@types/node
的模块
http
、
https
、
http2
泛型参数
RawServer
的默认值为
RawServerDefault
如果
RawServer
的类型为
http.Server
或
https.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
Reply
fastify.FastifyReply< RawServer , RawRequest , RawReply , RequestGeneric , ContextConfig >
该接口包含了 Fastify 添加到 Node.js 标准的 reply 对象上的属性。这些属性和 reply 对象的类型 (http 或 http2) 无关。
假如你需要为 FastifyReply 对象添加自定义属性 (例如使用
decorateReply
方法时),你应该针对该接口应用声明合并。
在
FastifyReply
里有基本的范例。更详细的例子请见“从例子中学习”的
插件
一节。
例子
import fastify from 'fastify'
const server = fastify()
server.decorateReply('someProp', 'world')
server.get('/', async (request, reply) => {
const { someProp } = reply //需要通过声明合并将该属性添加到 reply 接口上
return someProp
// 以下声明必须在 typescript 解释器的作用域内
declare module 'fastify' {
interface FastifyReply { // 引用的是接口而非类型
someProp: string
fastify.RawReplyDefaultExpression< RawServer >
依赖于
@types/node
的模块
http
、
https
、
http2
泛型参数
RawServer
的默认值为
RawServerDefault
如果
RawServer
的类型为
http.Server
或
https.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-plugin
。在“从例子中学习”的
插件
一节中有使用 TypeScript 创建插件的指南。
fastify.FastifyPluginCallback< Options >
fastify.register()
使用的接口方法定义。
fastify.FastifyPluginAsync< Options >
fastify.register()
使用的接口方法定义。
fastify.FastifyPlugin< Options >
fastify.register()
使用的接口方法定义。
通用的
FastifyPlugin
已不推荐使用,取而代之的是上述
FastifyPluginCallback
以及
FastifyPluginAsync
。这是因为
FastifyPlugin
无法正确推断出异步函数的类型。
fastify.FastifyPluginOptions
一个用于约束
fastify.register()
的
options
参数为对象类型的宽松类型对象 (loosely typed object)。在创建插件时,将插件的选项定义为此接口 (
interface MyPluginOptions extends FastifyPluginOptions
),传递给 register 方法。
Register
fastify.FastifyRegister(plugin: FastifyPluginCallback , opts: FastifyRegisterOptions )
fastify.FastifyRegister(plugin: FastifyPluginAsync , opts: FastifyRegisterOptions )
fastify.FastifyRegister(plugin: FastifyPlugin , opts: FastifyRegisterOptions )
指定
fastify.register()
类型的类型接口,返回一个拥有默认值为
FastifyPluginOptions
的
Options
泛型的函数签名。当调用此函数时,根据 FastifyPlugin 参数能推断出该泛型,因此不必特别指定。options 参数是插件选项以及
prefix: string
和
logLevel
(
LogLevel
) 两个属性的交叉类型。
以下例子展示了 options 的推断:
const server = fastify()
const plugin: FastifyPlugin<{
option1: string;