
为什么你的API文档总是过期swagger-blocks实时刷新机制与多环境文档实战【免费下载链接】swagger-blocksDefine and serve live-updating Swagger JSON for Ruby apps.项目地址: https://gitcode.com/gh_mirrors/sw/swagger-blocksswagger-blocks是一个 Ruby DSL 库让你在代码中用块block方式定义 Swagger/OpenAPI 文档并在每次请求时动态生成 Swagger JSON。它天生支持实时刷新——改完代码刷新页面文档立即更新彻底告别过期文档。为什么你的API文档总是过期 大多数项目的文档是这样维护的手动编辑一份静态的swagger.json或OpenAPI YAML接口改了文档没人记得改上线前才有人发现参数、类型、示例全对不上问题根源在于文档与代码分离。文档是一份快照而接口是活的。swagger-blocks 的思路正好相反文档本身就是代码。既然代码每次发版都经过审查和测试文档自然永远和接口同步。swagger-blocks 是什么一句话概括用纯 Ruby 代码块定义 API 文档自动构建兼容 Swagger UI 的 JSON。核心特点特性说明⚡ 实时刷新按设计支持 live updating改代码即改文档 框架无关Rails、Sinatra 等所有 Ruby Web 框架可用✅ 规格完备100% 支持 Swagger 2.0 全部特性同时支持 OpenAPI 3.0 1:1 命名块名与 Swagger 规范几乎一一对应学习成本极低它的模块入口是 lib/swagger/blocks.rblib/swagger/blocks.rb其中按autoload方式组织了swagger_root、swagger_path、swagger_schema等 30 多种节点类位于lib/swagger/blocks/nodes/目录下。实时刷新机制文档是如何活起来的1. 文档定义存放在类里而不是文件里通过include Swagger::Blocks任何 Ruby 类Controller、Model 甚至普通对象都能获得 DSL 能力。定义会被存成实例变量缓存在类上swagger_root→ 根节点swagger_root_nodeswagger_path→ 路径节点swagger_path_node_mapswagger_schema→ 模型节点swagger_schema_node_map这套机制实现在 lib/swagger/blocks/class_methods.rblib/swagger/blocks/class_methods.rb中。同一路径或模型被多次声明时会自动合并到已有节点所以你可以把同一接口的文档分散写在多个模块里。2. 每次请求现场生成 JSON关键在于这一行代码render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES)build_root_json定义在 lib/swagger/blocks/root.rblib/swagger/blocks/root.rb它的工作流程是遍历你传入的所有swaggered 类收集各自的节点内部逻辑见 lib/swagger/blocks/internal_helpers.rb即lib/swagger/blocks/internal_helpers.rb中的parse_swaggered_classes根据版本分别组装Swagger 2.0 挂载pathsdefinitionsOpenAPI 3.0 挂载pathscomponents返回可直接渲染的 JSON 对象因为 JSON 是请求时现算的所以没有过期一说——文档永远是代码的当前状态。3. 版本自动识别库会检查根节点中的版本号来区分 Swagger 2.0 与 OpenAPI 3.0逻辑在lib/swagger/blocks/class_methods.rb的version方法里声明key :openapi, 3.0.0就走 3.0 流程否则按 2.0 处理。两种规范可以共存于同一套代码。快速上手三步搭建实时文档第一步安装在 Gemfile 中加入gem swagger-blocks第二步用 DSL 写文档在 Controller 里定义接口路径与操作class PetsController ActionController::Base include Swagger::Blocks swagger_path /pets/{id} do operation :get do key :summary, Find Pet by ID parameter do key :name, :id key :in, :path key :required, true key :type, :integer end response 200 do key :description, pet response schema do key :$ref, :Pet end end end end end在 Model 里定义可复用的数据结构Schemaclass Pet ActiveRecord::Base include Swagger::Blocks swagger_schema :Pet do key :required, [:id, :name] property :id do key :type, :integer key :format, :int64 end property :name do key :type, :string end end end第三步提供一个文档接口class ApidocsController ActionController::Base include Swagger::Blocks swagger_root do key :swagger, 2.0 info do key :version, 1.0.0 key :title, Swagger Petstore end end SWAGGERED_CLASSES [PetsController, Pet, self].freeze def index render json: Swagger::Blocks.build_root_json(SWAGGERED_CLASSES) end end⚠️常见坑如果报错swagger_root must be declared检查SWAGGERED_CLASSES里是否包含了声明swagger_root的那个类也就是self。这个校验逻辑在lib/swagger/blocks/internal_helpers.rb的limit_root_node方法中。最后让 Swagger UI 指向/apidocs即可。改任何一处 block 定义刷新 Swagger UI 就能看到变化——这就是实时刷新。小贴士如果不想直接对外提供 JSON也可以用build_root_json把文档导出到文件swagger_data Swagger::Blocks.build_root_json(SWAGGERED_CLASSES) File.open(swagger.json, w) { |file| file.write(swagger_data.to_json) }多环境文档实战因为文档是动态计算的按环境展示不同 API变得异常简单。这正是 swagger-blocks 主打的灵活性可以用 initializer、配置对象来改值甚至让不同环境渲染不同的接口集合。方案一用环境变量切换 host / serverswagger_root do key :swagger, 2.0 key :host, ENV.fetch(SWAGGER_HOST, api.example.com) key :basePath, /api end生产环境设置SWAGGER_HOSTapi.prod.com预发环境设置为测试域名文档自动跟随。方案二条件声明只暴露当前环境的接口if Rails.env.production? swagger_path /internal/jobs do operation :post do key :summary, Internal use only end end end内部接口在开发环境的文档里根本不会出现天然实现了文档脱敏。方案三运行时覆盖属性如果某些属性需要临时定制可以包装自己的构建方法做哈希合并def build_and_override_root_json(overrides {}) Swagger::Blocks.build_root_json(SWAGGERED_CLASSES).merge(overrides) end方案四OpenAPI 3.0 的 Server 变量在 3.0 模式下server块支持variable子块可以在文档页面让用户自己选择子域名和版本server do key :url, https://{subdomain}.site.com/{version} variable :subdomain do key :default, :production end variable :version do key :enum, [v1, v2] key :default, :v2 end end完整的多环境示例可参考测试文件 spec/lib/swagger_v3_blocks_spec.rbspec/lib/swagger_v3_blocks_spec.rb它演示了 server、变量、安全方案等 3.0 特性。减少样板代码的三个技巧1️⃣参数复用在swagger_root中声明一次参数各operation中直接引用避免重复定义。2️⃣内联键任何块都支持内联 hash 写法三种写法完全等价parameter paramType: :path, name: :petId do key :description, ID of pet to fetch end3️⃣可复用响应模块401/404 等通用响应封装成 moduleextend进 operation 即可省去重复声明。项目结构速览路径作用lib/swagger/blocks.rb模块入口autoload 各节点类lib/swagger/blocks/root.rbbuild_root_json核心构建逻辑lib/swagger/blocks/class_methods.rbswagger_root/swagger_path/swagger_schemaDSLlib/swagger/blocks/internal_helpers.rb节点收集、合并与校验lib/swagger/blocks/node.rb节点基类lib/swagger/blocks/nodes/30 种节点schema、response、security_scheme 等spec/lib/swagger_v2_blocks_spec.rbSwagger 2.0 完整示例spec/lib/swagger_v3_blocks_spec.rbOpenAPI 3.0 完整示例常见问题 FAQQ必须用 Rails 吗不用。它是纯 Ruby 实现任何 Ruby Web 框架Sinatra、Hanami 等都能用甚至可以在普通脚本里构建文档。Q支持 Swagger 1.2 吗2.0.0 版本起不再支持 1.2请升级规范或锁定旧版 gem。Q性能有影响吗JSON 是请求时构建的。对文档接口这种低频访问场景完全可以接受如有需要可对build_root_json的结果做一层缓存接口变更时主动失效即可。总结✅ 文档过期的本质是文档与代码分离。swagger-blocks 把 Swagger 文档变成 Ruby 代码用请求时动态生成 JSON的机制保证文档与接口永远同步。✅ 上手只需三步includeDSL、写swagger_path/swagger_schema、一个接口调用build_root_json。✅ 多环境文档不是额外功能而是动态生成的天然红利——环境变量、条件声明、运行时覆盖三种姿势任选。如果你正在维护一个 Ruby 后端 API不妨把下一份文档从静态文件迁移到代码里体验一次改完即生效的文档开发流程。【免费下载链接】swagger-blocksDefine and serve live-updating Swagger JSON for Ruby apps.项目地址: https://gitcode.com/gh_mirrors/sw/swagger-blocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考