fastify by bobmatnyc/claude-mpm-skills
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill fastifyFastify 是一个高性能的 Node.js Web 框架,围绕 JSON 模式验证、封装的插件和出色的开发者体验构建。在 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"); // 启动竞争并隐藏绑定失败
Fastify 通过 JSON 模式验证请求/响应。使用类型提供器可以避免类型重复定义。
✅ 正确:Zod 模式驱动验证 + 类型
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 });
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
✅ 正确:TypeBox 模式
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"));
无需绑定端口,在内存中测试路由。
✅ 正确:注入请求
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" });
});
});
main.ts 中;应将路由和依赖项隔离到插件中。每周安装量
257
代码仓库
GitHub 星标数
27
首次出现
2026年1月23日
安全审计
安装于
opencode210
codex208
gemini-cli206
github-copilot206
cursor173
kimi-cli170
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.
✅ Correct: basic server with typed response
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
app.listen({ port: 3000 });
console.log("started"); // races startup and hides bind failures
Fastify validates requests/responses via JSON schema. Use a type provider to avoid duplicating types.
✅ Correct: Zod schema drives validation + types
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 });
✅ Correct: 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 });
Use plugins to keep concerns isolated and testable (auth, db, routes).
✅ Correct: route plugin
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
app.register(usersRoutes, { prefix: "/api/v1/users" });
Centralize unexpected failures and return stable error shapes.
✅ Correct: setErrorHandler
app.setErrorHandler((err, req, reply) => {
req.log.error({ err }, "request failed");
reply.status(500).send({ error: "internal" as const });
});
Add standard security plugins and enforce payload limits.
✅ Correct: Helmet + CORS + rate limiting
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" });
Close HTTP server and downstream clients (DB, queues) on SIGINT/SIGTERM.
✅ Correct: close on signals
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"));
Test routes in-memory without binding ports.
✅ Correct: inject request
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" });
});
});
main.ts; isolate routes and dependencies into plugins.Weekly Installs
257
Repository
GitHub Stars
27
First Seen
Jan 23, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode210
codex208
gemini-cli206
github-copilot206
cursor173
kimi-cli170
飞书视频会议CLI工具:lark-vc技能详解,高效搜索与管理会议记录与纪要
14,500 周安装
系统设计框架:大规模分布式系统设计原则、四步流程与构建模块详解
251 周安装
Gluestack UI v4 设计模式指南:React Native 组件库样式规范与最佳实践
251 周安装
Notion知识捕获插件:将对话内容自动转化为结构化文档,提升团队知识管理效率
251 周安装
Shopify开发技能 - 集成ClaudeKit的电商自动化与AI助手解决方案
251 周安装
Hono Cloudflare Workers 教程 - 构建边缘API与无服务器应用
252 周安装
阿里云OpenSearch向量检索版使用指南:Python SDK推送文档与HA/SQL搜索教程
252 周安装