fastify
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFastify (TypeScript) - Production Backend Framework
Fastify(TypeScript)- 生产级后端框架
Overview
概述
Fastify is a high-performance Node.js web framework built around JSON schema validation, encapsulated plugins, and great developer ergonomics. In TypeScript, pair Fastify with a type provider (Zod or TypeBox) to keep runtime validation and static types aligned.
Fastify是一个基于JSON Schema校验、封装式插件和良好开发者体验构建的高性能Node.js Web框架。在TypeScript环境中,可将Fastify与类型提供器(Zod或TypeBox)配合使用,确保运行时校验与静态类型保持一致。
Quick Start
快速开始
Minimal server
最简服务器
✅ Correct: basic server with typed response
ts
import Fastify from "fastify";
const app = Fastify({ logger: true });
app.get("/health", async () => ({ status: "ok" as const }));
await app.listen({ host: "0.0.0.0", port: 3000 });❌ Wrong: start server without awaiting listen
ts
app.listen({ port: 3000 });
console.log("started"); // races startup and hides bind failures✅ 正确示例:带类型化响应的基础服务器
ts
import Fastify from "fastify";
const app = Fastify({ logger: true });
app.get("/health", async () => ({ status: "ok" as const }));
await app.listen({ host: "0.0.0.0", port: 3000 });❌ 错误示例:不等待listen就启动服务器
ts
app.listen({ port: 3000 });
console.log("started"); // 会与启动过程竞争,且隐藏绑定失败信息Schema Validation + Type Providers
Schema校验 + 类型提供器
Fastify validates requests/responses via JSON schema. Use a type provider to avoid duplicating types.
Fastify通过JSON Schema对请求/响应进行校验。使用类型提供器可避免类型重复定义。
Zod provider (recommended for full-stack TypeScript)
Zod提供器(推荐用于全栈TypeScript项目)
✅ Correct: Zod schema drives validation + types
ts
import Fastify from "fastify";
import { z } from "zod";
import { ZodTypeProvider } from "fastify-type-provider-zod";
const app = Fastify({ logger: true }).withTypeProvider<ZodTypeProvider>();
const Query = z.object({ q: z.string().min(1) });
app.get(
"/search",
{ schema: { querystring: Query } },
async (req) => {
return { q: req.query.q };
},
);
await app.listen({ port: 3000 });✅ 正确示例:Zod Schema驱动校验与类型
ts
import Fastify from "fastify";
import { z } from "zod";
import { ZodTypeProvider } from "fastify-type-provider-zod";
const app = Fastify({ logger: true }).withTypeProvider<ZodTypeProvider>();
const Query = z.object({ q: z.string().min(1) });
app.get(
"/search",
{ schema: { querystring: Query } },
async (req) => {
return { q: req.query.q };
},
);
await app.listen({ port: 3000 });TypeBox provider (recommended for OpenAPI + performance)
TypeBox提供器(推荐用于OpenAPI与高性能场景)
✅ Correct: TypeBox schema
ts
import Fastify from "fastify";
import { Type } from "@sinclair/typebox";
import { TypeBoxTypeProvider } from "@fastify/type-provider-typebox";
const app = Fastify({ logger: true }).withTypeProvider<TypeBoxTypeProvider>();
const Params = Type.Object({ id: Type.String({ minLength: 1 }) });
const Reply = Type.Object({ id: Type.String() });
app.get(
"/users/:id",
{ schema: { params: Params, response: { 200: Reply } } },
async (req) => ({ id: req.params.id }),
);
await app.listen({ port: 3000 });✅ 正确示例:TypeBox Schema
ts
import Fastify from "fastify";
import { Type } from "@sinclair/typebox";
import { TypeBoxTypeProvider } from "@fastify/type-provider-typebox";
const app = Fastify({ logger: true }).withTypeProvider<TypeBoxTypeProvider>();
const Params = Type.Object({ id: Type.String({ minLength: 1 }) });
const Reply = Type.Object({ id: Type.String() });
app.get(
"/users/:id",
{ schema: { params: Params, response: { 200: Reply } } },
async (req) => ({ id: req.params.id }),
);
await app.listen({ port: 3000 });Plugin Architecture (Encapsulation)
插件架构(封装性)
Use plugins to keep concerns isolated and testable (auth, db, routes).
✅ Correct: route plugin
ts
import type { FastifyPluginAsync } from "fastify";
export const usersRoutes: FastifyPluginAsync = async (app) => {
app.get("/", async () => [{ id: "1" }]);
app.get("/:id", async (req) => ({ id: (req.params as any).id }));
};✅ Correct: register with a prefix
ts
app.register(usersRoutes, { prefix: "/api/v1/users" });使用插件可实现关注点分离,提升可测试性(如鉴权、数据库、路由等)。
✅ 正确示例:路由插件
ts
import type { FastifyPluginAsync } from "fastify";
export const usersRoutes: FastifyPluginAsync = async (app) => {
app.get("/", async () => [{ id: "1" }]);
app.get("/:id", async (req) => ({ id: (req.params as any).id }));
};✅ 正确示例:带前缀注册插件
ts
app.register(usersRoutes, { prefix: "/api/v1/users" });Error Handling
错误处理
Centralize unexpected failures and return stable error shapes.
✅ Correct: setErrorHandler
ts
app.setErrorHandler((err, req, reply) => {
req.log.error({ err }, "request failed");
reply.status(500).send({ error: "internal" as const });
});集中处理意外故障,返回稳定的错误格式。
✅ 正确示例:设置setErrorHandler
ts
app.setErrorHandler((err, req, reply) => {
req.log.error({ err }, "request failed");
reply.status(500).send({ error: "internal" as const });
});Security Hardening (Baseline)
安全加固(基础配置)
Add standard security plugins and enforce payload limits.
✅ Correct: Helmet + CORS + rate limiting
ts
import helmet from "@fastify/helmet";
import cors from "@fastify/cors";
import rateLimit from "@fastify/rate-limit";
await app.register(helmet);
await app.register(cors, { origin: false });
await app.register(rateLimit, { max: 100, timeWindow: "1 minute" });添加标准安全插件并限制负载大小。
✅ 正确示例:Helmet + CORS + 速率限制
ts
import helmet from "@fastify/helmet";
import cors from "@fastify/cors";
import rateLimit from "@fastify/rate-limit";
await app.register(helmet);
await app.register(cors, { origin: false });
await app.register(rateLimit, { max: 100, timeWindow: "1 minute" });Graceful Shutdown
优雅停机
Close HTTP server and downstream clients (DB, queues) on SIGINT/SIGTERM.
✅ Correct: close on signals
ts
const close = async (signal: string) => {
app.log.info({ signal }, "shutting down");
await app.close();
process.exit(0);
};
process.on("SIGINT", () => void close("SIGINT"));
process.on("SIGTERM", () => void close("SIGTERM"));在收到SIGINT/SIGTERM信号时,关闭HTTP服务器及下游客户端(数据库、队列等)。
✅ 正确示例:监听信号并关闭服务
ts
const close = async (signal: string) => {
app.log.info({ signal }, "shutting down");
await app.close();
process.exit(0);
};
process.on("SIGINT", () => void close("SIGINT"));
process.on("SIGTERM", () => void close("SIGTERM"));Testing (Fastify inject)
测试(Fastify inject)
Test routes in-memory without binding ports.
✅ Correct: inject request
ts
import Fastify from "fastify";
import { describe, it, expect } from "vitest";
describe("health", () => {
it("returns ok", async () => {
const app = Fastify();
app.get("/health", async () => ({ status: "ok" as const }));
const res = await app.inject({ method: "GET", url: "/health" });
expect(res.statusCode).toBe(200);
expect(res.json()).toEqual({ status: "ok" });
});
});无需绑定端口,在内存中测试路由。
✅ 正确示例:注入请求测试
ts
import Fastify from "fastify";
import { describe, it, expect } from "vitest";
describe("health", () => {
it("returns ok", async () => {
const app = Fastify();
app.get("/health", async () => ({ status: "ok" as const }));
const res = await app.inject({ method: "GET", url: "/health" });
expect(res.statusCode).toBe(200);
expect(res.json()).toEqual({ status: "ok" });
});
});Decision Trees
决策树
Fastify vs Express
Fastify vs Express
- Prefer Fastify for schema-based validation, predictable plugins, and high throughput.
- Prefer Express for minimal middleware and maximal ecosystem familiarity.
- 若需要基于Schema的校验、可预测的插件和高吞吐量,优先选择Fastify。
- 若需要极简中间件和最大的生态系统熟悉度,优先选择Express。
Zod vs TypeBox
Zod vs TypeBox
- Prefer Zod for app codebases that already standardize on Zod (forms, tRPC, shared types).
- Prefer TypeBox for OpenAPI generation and performance-critical validation.
- 若项目已标准化使用Zod(如表单、tRPC、共享类型),优先选择Zod。
- 若需要生成OpenAPI和高性能校验,优先选择TypeBox。
Anti-Patterns
反模式
- Skip request validation; validate at boundaries with schemas.
- Register everything in ; isolate routes and dependencies into plugins.
main.ts - Return raw error objects; return stable error shapes and log the details.
- 跳过请求校验;应通过Schema在边界处进行校验。
- 所有内容都注册在中;应将路由和依赖项隔离到插件中。
main.ts - 返回原始错误对象;应返回稳定的错误格式并记录详细信息。
Resources
资源
- Fastify: https://www.fastify.io/
- fastify-type-provider-zod: https://github.com/turkerdev/fastify-type-provider-zod
- @fastify/type-provider-typebox: https://github.com/fastify/fastify-type-provider-typebox
- Fastify: https://www.fastify.io/
- fastify-type-provider-zod: https://github.com/turkerdev/fastify-type-provider-zod
- @fastify/type-provider-typebox: https://github.com/fastify/fastify-type-provider-typebox