资讯动态

Fastify 深入浅出

发布时间:2026/10/18 1:34:37 来源:尧图企业网站定制
目录前言一、Fastify 概览二、入门快速示例最小可运行三、核心概念详解1、请求/响应 API2、SchemaJSON Schema3、Hooks生命周期钩子4、Decorators扩展实例/请求/回复5、Encapsulation封装四、插件系统最重要的机制1、注册插件2、fastify-plugin3、autoload自动加载五、性能相关为什么 Fastify 快如何优化1、性能来源2、性能优化建议3、Threadpool 与 CPU 密集六、TypeScript 与 Fastify企业级要点1、基本 TypeScript 快速示例2、类型扩展decorate、plugin3、推荐工具链七、路由与分层架构最佳实践1、项目结构建议2、路由封装示例八、安全必做项九、错误处理与日志十、测试单元、集成、端到端十一、常用与推荐插件企业级清单十二、Express 到 Fastify 的迁移实务要点十三、部署与扩容生产实践十四、监控指标 健康检查建议十五、常见问题与排查指南十六、性能调优 checklist落地十七、实战示例一个带 Auth、DB、Swagger 的项目骨架关键代码片段十八、Fastify 与其他框架对比简要前言Fastify 中文官方文档一、Fastify 概览定义Fastify是一个以性能与开发者体验为目标的Node.js web 框架。核心特点高性能序列化优化插件/封装机制内置 schema 驱动校验与序列化优秀的 TypeScript 支持适用场景高并发 API 服务微服务BFFServerless设计原则低开销的请求/响应序列化使用 fast-json-stringify 优化 JSON 序列化。schema-first用 JSON Schema 描述请求/响应自动校验和序列化性能更好。插件封装encapsulation通过插件隔离作用域、依赖注入、避免全局污染。尽量少做魔法明确生命周期 hook便于调试。插件生态大量插件认证、Swagger、Redis、db 客户端等。二、入门快速示例最小可运行// index.jsconstfastifyrequire(fastify)({logger:true});fastify.get(/,async(request,reply){return{hello:world};});conststartasync(){try{await fastify.listen({port:3000});console.log(Server listening on 3000);}catch(err){fastify.log.error(err);process.exit(1);}};start();运行nodeindex.js三、核心概念详解1、请求/响应 APIfastify.get/post/put/delete(path, opts, handler)支持返回 Promise 或直接 reply.send()。request包含 params, query, body, headers, raw原生 req。reply封装了 res有 reply.code(201).send(obj), reply.header(‘x’, ‘y’) 等。示例fastify.post(/user/:id,async(request,reply){const{id}request.params;constbodyrequest.body;reply.code(201).send({id,...body});});2、SchemaJSON Schema在 opts.schema 中定义 querystring, params, body, headers, response。Fastify 在接收请求时会校验基于 AJV在返回时会序列化/校验响应。schema 带来性能优化编译一次后复用。示例fastify.route({method:POST,url:/user,schema:{body:{type:object,required:[name],properties:{name:{type:string}}},response:{201:{type:object,properties:{id:{type:number}}}}},handler:async(req,reply){/*...*/}});3、Hooks生命周期钩子常见 hooks执行顺序onRequest — 在请求到达时执行可用于认证、速率限制。preParsing — 原始 body 解析前。preValidation — 校验前可修改请求。preHandler — 校验后、handler 前常用于权限。preSerialization — 响应序列化前可处理数据。onSend — 响应发送前最后改 header。onResponse — 响应完成后用于日志、清理。onTimeout / onError 等特殊钩子。示例fastify.addHook(onRequest,async(req,reply){// 认证});4、Decorators扩展实例/请求/回复fastify.decorate(name, value)添加到 Fastify 实例可在插件中注入。fastify.decorateRequest(‘foo’, null) / fastify.decorateReply(‘bar’, null)为 request/reply 增加方法/字段。【注意】装饰要与 encapsulation 协调避免跨插件冲突。示例fastify.decorate(utils,{uuid:()...});fastify.decorateRequest(user,null);5、Encapsulation封装插件之间默认是封装的子插件的 decorate 不会泄露给父插件之外的插件除非你显式设置 fastify.register() 的 options。这是 Fastify 防止全局污染的核心机制你可以为每个模块创建独立上下文依赖注入、安全隔离。四、插件系统最重要的机制1、注册插件fastify.register(require(fastify/sqlite),{dbFile::memory:});注册后插件可以使用 fastify.decorate 注入 db 实例或其他工具。2、fastify-plugin用于将一个函数标记为 Fastify 插件并可设置依赖。示例constfprequire(fastify-plugin);module.exportsfp(async(fastify,opts){fastify.decorate(service,newService(opts));},{name:my-service,dependencies:[fastify/sqlite]});3、autoload自动加载fastify-autoload 可以按照目录结构自动加载插件、路由适合大型项目约定成俗的结构。五、性能相关为什么 Fastify 快如何优化1、性能来源JSON 序列化使用 fast-json-stringify针对 schema 生成快速序列化函数比 JSON.stringify 在某些场景快。Schema 驱动减少运行期校验开销编译一次复用。更少中间件抽象层低 overhead。2、性能优化建议使用 schema为请求和响应都加 schema能显著提速。避免在热路由上做大量同步工作同步计算会阻塞事件循环。使用 reply.serializer自定义序列化仅在必要时。复用单例资源DB 连接池但注意封装作用域。开启 HTTP keep-alive、合理设置 maxSockets在客户端或代理中。批量响应/压缩使用 fastify/compress 启用 gzip/brotli。在高并发下使用 cluster 或进程管理PM2 / Kubernetes扩展。3、Threadpool 与 CPU 密集Fastify 本身是单线程 JS。CPU 耗时操作应用 worker_threads 或把任务下放给后台微服务。六、TypeScript 与 Fastify企业级要点Fastify 对 TypeScript 支持很好但要注意类型扩展与插件的类型。1、基本 TypeScript 快速示例importFastifyfromfastify;constfastifyFastify({logger:true});fastify.get(/,async(request,reply){return{hello:world};});2、类型扩展decorate、plugin如果插件 decorate 了 fastify.foo需在类型声明中扩展 FastifyInstance 接口declaremodulefastify{interface FastifyInstance{service:MyService;}}对于 request.body 等使用泛型指定 route 的 schema typesfastify.post{Body:{name:string}}(/user,async(request,reply){constnamerequest.body.name;});3、推荐工具链ts-node-dev开发阶段构建到 JStsc / esbuild用于生产使用 fastify-cli 创建 TS 项目模板七、路由与分层架构最佳实践1、项目结构建议src/server.ts plugins/db.ts auth.ts routes/users/index.ts// 注册子路由handlers.ts schema.ts services/userService.ts utils/types/使用 fastify-autoload 自动加载 plugins 和 routes配合 fastify-plugin 做依赖注入。2、路由封装示例routes/users/index.tsimport{FastifyPluginAsync}fromfastify;importhandlersfrom./handlers;importschemafrom./schema;constusers:FastifyPluginAsyncasync(fastify){fastify.get(/,{schema:schema.list},handlers.list);fastify.get(/:id,{schema:schema.get},handlers.get);};exportdefaultusers;八、安全必做项使用 fastify/helmet 添加安全头CSP、X-Frame、XSS。使用 fastify/rate-limit 防止滥用DoS、暴力破解。使用 fastify/cors 配置 CORS 白名单。校验输入schema以防注入攻击。在生产中禁用详细错误输出使用统一错误结构error handler。示例fastify.register(require(fastify/helmet));fastify.register(require(fastify/rate-limit),{max:100,timeWindow:1 minute});fastify.register(require(fastify/cors),{origin:[https://your.app]});九、错误处理与日志使用 setErrorHandler 自定义错误格式与日志fastify.setErrorHandler((error,request,reply){request.log.error(error);reply.status(error.statusCode||500).send({error:error.message});});内置 logger 使用 pino性能优秀。生产建议把日志输出到 stdout 并由日志聚合系统采集。十、测试单元、集成、端到端推荐使用 tapFastify 官方示例或 Jest supertest。fastify.inject() 可以直接模拟请求不需要启动网络端口非常适合单元/集成测试。示例tapconsttrequire(tap);constFastifyrequire(fastify);t.test(GET /,async t{constappFastify();app.get(/,async()({ok:true}));constresawait app.inject({method:GET,url:/});t.equal(res.statusCode,200);t.same(JSON.parse(res.payload),{ok:true});await app.close();});十一、常用与推荐插件企业级清单fastify/helmet — 安全头fastify/cors — CORSfastify/compress — gzip/brotlifastify/jwt — JWT 认证fastify/oauth2 — OAuth2 客户端fastify/rate-limit — 限流fastify/swagger / fastify/openapi-glue — 自动生成 API 文档fastify/sqlite, fastify/postgres — DB 连接fastify-autoload — 自动加载插件/路由fastify-plugin — 标记插件fastify-sensible — 常用响应工具httpErrors 等fastify-formbody — 解析 form bodyfastify-static — 静态文件fastify-multipart — 文件上传stream 支持十二、Express 到 Fastify 的迁移实务要点路由语法类似但要改造 middlewareExpress 中间件需用 fastify-express 或改写为 Fastify hooks/plugins。注意Express 全局中间件在 Fastify 中要转成 hook 或封装插件。req/res 对象不同Fastify 提供 request.raw 和 reply.raw 访问原生 node 对象。推荐逐步迁移把路由逐个转换为 Fastify plugin使用 fastify.register() 提高可维护性。十三、部署与扩容生产实践多进程使用 cluster、PM2 或容器编排K8s将应用扩展到多核。反向代理通常前面放 Nginx / Envoy 做 TLS 终端、静态缓存、负载均衡。资源监控pino 日志 Prometheus 指标导出prom-client Grafana。健康探针提供 /healthz readiness 和 liveness endpoints。容器镜像使用多阶段构建生产镜像只包含运行时产物用非 root 用户运行。示例 DockerfileFROM node:20-alpine AS builder WORKDIR/app COPY package*.json./RUN npm ci COPY..RUN npm run build FROM node:20-alpine WORKDIR/app COPY--frombuilder/app./ENV NODE_ENVproduction RUN npm ci--production USER node CMD[node,dist/index.js]十四、监控指标 健康检查建议导出常见指标响应时间、错误率、event loop lag、heap usage并在 K8s HPA 中使用自定义指标。快速导出 event loop lagconst{monitorEventLoopDelay}require(perf_hooks);consthmonitorEventLoopDelay();h.enable();setInterval((){// expose h.mean/h.max to prometheus},5000);十五、常见问题与排查指南高延迟但 CPU 很低可能外部依赖慢DB、HTTP加超时与熔断检查连接池。内存泄漏 / OOM进行 heapdump 分析检查全局缓存、未关闭的连接与未清的定时器。大量 502/504代理超时、后端资源耗尽或死锁。检查 Nginx 配置与 keepalive。schema 校验报错查看 schema 的 compiled errors注意 additionalProperties 默认行为。插件冲突检查 encapsulation是否意外 decorate 全局变量名重复。十六、性能调优 checklist落地使用 schema请求 响应。在高频 API 使用 response.schema fast-json-stringify 的序列化优势。避免常见阻塞同步 IO、大对象 JSON.stringify。启用 fastify/compress 并选择合适压缩算法brotli 在静态资源上优异。使用 pino 并输出到 stdout不会阻塞主线程。对大文件上传使用 streamfastify-multipart。将 CPU 密集任务用 worker_threads 容器化或微服务化。在 K8s 中设置合理的资源 requests/limits使用 HPA。十七、实战示例一个带 Auth、DB、Swagger 的项目骨架关键代码片段src/server.tsimportFastifyfromfastify;importautoloadfromfastify-autoload;importpathfrompath;constfastifyFastify({logger:true});fastify.register(require(fastify/helmet));fastify.register(require(fastify/cors),{origin:true});fastify.register(require(fastify/compress));fastify.register(autoload,{dir:path.join(__dirname,plugins)});fastify.register(autoload,{dir:path.join(__dirname,routes)});fastify.listen({port:3000}).then(()fastify.log.info(Server started));src/plugins/db.tsimportfpfromfastify-plugin;import{Database}fromsome-db-lib;exportdefaultfp(asyncfunction(fastify,opts){constdbnewDatabase(opts);fastify.decorate(db,db);fastify.addHook(onClose,async(){await db.close();});});src/routes/users/index.tsimportfpfromfastify-plugin;exportdefaultasyncfunction(fastify){fastify.get(/users,{schema:{response:{200:{type:array,items:{type:object}}}}},async(req,reply){returnawait fastify.db.getUsers();});}十八、Fastify 与其他框架对比简要Express生态大、学习门槛低但性能与 schema 支持较弱。迁移到 Fastify 可获得性能和类型优势。Koa语法优雅、基于 async/await中间件更简洁Fastify 更注重性能与插件封装。NestJS企业级架构DI、模块化。Nest 可以选择 Fastify 作为底层 HTTP adapter得到两者优点。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑