mcpField
F
fastify

fastify

github.com/bobmatnyc开发78575 次安装15 周前更新
代码仓库

关于 fastify

面向 TypeScript 开发者的 Fastify Node.js 后端构建指南,重点介绍模式验证、封装式插件、错误处理、安全措施、优雅关闭和内存路由测试。

主要功能

  1. 01用模式验证请求和响应
  2. 02通过封装式插件组织路由
  3. 03集中处理错误
  4. 04应用安全插件并限制载荷
  5. 05响应进程信号并优雅关闭
  6. 06通过内存注入测试路由

适用场景

  1. 01构建类型化的 Node.js HTTP API
  2. 02分离路由与依赖逻辑
  3. 03让处理器返回一致的错误
  4. 04无需开放端口即可测试端点

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill fastify

安装后在 Claude Code 中输入/fastify确认已加载。

附带文件metadata.json

详细介绍

Fastify(TypeScript)- 生产级后端框架

概述

Fastify 是一个高性能 Node.js Web 框架,基于 JSON Schema 验证、封装式插件和出色的开发体验构建。在 TypeScript 中,将 Fastify 与类型提供程序(Zod 或 TypeBox)搭配使用,可确保运行时验证与静态类型保持一致。

快速开始

最简服务器

✅ 正确:带类型响应的基本服务器

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

app.listen({ port: 3000 });
console.log("started"); // races startup and hides bind failures

Schema 验证 + 类型提供程序

Fastify 通过 JSON Schema 验证请求和响应。使用类型提供程序可避免重复定义类型。

Zod 提供程序(推荐用于全栈 TypeScript)

✅ 正确:Zod Schema 驱动验证和类型

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 提供程序(推荐用于 OpenAPI + 性能)

✅ 正确:TypeBox Schema

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 });

插件架构(封装)

使用插件隔离各项职责,便于测试(身份验证、数据库、路由)。

✅ 正确:路由插件

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 }));
};

✅ 正确:注册时添加前缀

app.register(usersRoutes, { prefix: "/api/v1/users" });

错误处理

集中处理意外故障,并返回稳定的错误结构。

✅ 正确:setErrorHandler

app.setErrorHandler((err, req, reply) => {
  req.log.error({ err }, "request failed");
  reply.status(500).send({ error: "internal" as const });
});

安全加固(基线)

添加标准安全插件并限制负载大小。

✅ 正确:Helmet + CORS + 速率限制

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" });

优雅关闭

在 SIGINT/SIGTERM 时关闭 HTTP 服务器及下游客户端(数据库、队列)。

✅ 正确:在信号触发时关闭

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"));

测试(Fastify inject)

在内存中测试路由,无需绑定端口。

✅ 正确:注入请求

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" });
  });
});

决策树

Fastify 与 Express
  • 如果需要基于 Schema 的验证、可预测的插件机制和高吞吐量,优先选择 Fastify。
  • 如果需要精简的中间件和对生态系统的高度熟悉度,优先选择 Express。
Zod 与 TypeBox
  • 如果应用代码库已统一使用 Zod(表单、tRPC、共享类型),优先选择 Zod。
  • 如果需要生成 OpenAPI 文档和进行性能关键型验证,优先选择 TypeBox。

反模式

  • 跳过请求验证;应在边界处使用 Schema 进行验证。
  • 将所有内容都注册在 main.ts 中;应将路由和依赖隔离到插件中。
  • 返回原始错误对象;应返回稳定的错误结构,并记录详细信息。

资源

评论

支持 Markdown