跳转到主要内容

Swagger 插件

本页覆盖这三个模板:

  • lynx-swagger/conf/swagger-simple.yml
  • lynx-swagger/conf/swagger.yml
  • lynx-swagger/conf/swagger-secure.yml

关键现实是:当前运行时读取的是 swagger.go 里的自定义 YAML 结构,而不是把 protobuf / 模板字段一比一全部接线。模板里有些键是 live 的,有些已经过时,有些还改了名字。

Runtime 事实

项目
Go 模块github.com/go-lynx/lynx-swagger
配置前缀lynx.swagger
Runtime 插件名swagger
Getter 边界只有实例方法 (*PlugSwagger).GetSwagger();不存在 package-level swagger.GetSwagger()

配置前先知道

  • 运行时会读取 lynx.swagger.enabledgeneratoruiinfosecurityapi_server
  • api_server.host 是 Swagger UI 里 “Try it out” 真正会调用的后端地址;留空时插件会尝试从 lynx.http.addr 推导。
  • 真正的文件监听开关是 generator.watch_files。模板里的 watch_enabled 当前运行时并不会读取。
  • 模板里的 ui.title 当前没有运行时效果,页面标题实际上来自 info.title
  • ui.deep_linkingui.doc_expansionui.display_request_durationui.default_models_expand_depth 都是模板时代的 snake_case 键;当前结构体期望 camelCase,而且真正渲染到 UI HTML 的只有 deepLinkingdocExpansion
  • 模板里的 info.terms_of_service 不会映射到当前运行时字段,当前结构体期望的是 termsOfService
  • serversbase_pathschemesconsumesproducestagsexternal_docssecurity_definitions、顶层 Swagger security 要求,以及 advanced 目前都不会被运行时 YAML 结构消费。
  • disable_in_production 在当前实现里几乎总会被强制保持为 true,因为 SetDefaultValues() 会把 false 又改回 true。实际效果是:除非改代码,生产和 staging 仍会被拦住。

当前运行时真正读取的键

字段作用何时生效默认值 / 交互关系常见误配
enabled打开或关闭整个 Swagger 插件。启动时。默认 true在不该暴露文档面的环境里忘了关闭。
generator.enabled打开注解扫描和文档重建。启动时与文件变更时。默认 true;若设为 falseui.enabled: true,就仍然需要 generator.spec_files关掉生成,却又没提供任何可展示的 spec 文件。
generator.spec_files在注解扫描前先加载外部 Swagger/OpenAPI 文件。启动和重建时。可选,但如果 generator 关闭而 UI 还要开,它就变成必需项。指到工作区外的路径;当前校验会拒绝工作区外路径。
generator.scan_dirs指定扫描 Go 注解的目录。generator.enabled: true没配时默认 ["./"]加入不存在目录,或把仓库外路径塞进来。
generator.output_path把合并后的文档写回磁盘。每次重建后。默认 ./docs/openapi.yaml;以 .yaml / .yml 结尾写 YAML,其他后缀写 JSON。误以为保存文件名由 spec_url 决定。
generator.watch_files打开扫描目录的文件监听。仅生成开启且 scan_dirs 非空时。默认 true还在用模板里的 watch_enabled,却以为 watcher 已被改掉。
ui.enabled启动或跳过 Swagger UI HTTP 服务。启动时。默认 true关了 UI 后还去浏览器找 /swagger
ui.portSwagger UI HTTP 服务监听端口。ui.enabled: true默认 8081;合法范围 1024..65535lynx-http 业务端口复用,导致端口冲突。
ui.pathSwagger UI 路由前缀。ui.enabled: true默认 /swagger;必须以 / 开头。忘了写前导斜杠。
info.title设置 OpenAPI 标题,同时也是当前 HTML 包装页使用的页面标题。启动时和重建时。默认 API Documentation只改 ui.title,却疑惑页面标题没变。
info.description设置 OpenAPI 描述。重建时。可选。把大量运维说明硬塞进这里,而不是链到外部文档。
info.version设置 OpenAPI 版本号。重建时。默认 1.0.0把它当部署 SHA,而不是 API 版本。
info.contact.name设置 spec 联系人名字。重建时。可选。团队归属变了却没更新。
info.contact.email设置 spec 联系邮箱。重建时。可选。对外文档里仍暴露一个失效邮箱。
info.contact.url设置 spec 联系链接。重建时。可选。外部文档指向内部地址。
info.license.name设置 spec 许可证名称。重建时。可选。和仓库真实 license 不一致。
info.license.url设置 spec 许可证链接。重建时。可选。法务链接已过期。
security.environment标记当前环境,用于允许列表校验。启动校验时。默认 development忘了 ENVGO_ENVAPP_ENV 会覆盖这个值。
security.allowed_environments允许插件运行的环境列表。启动校验时。默认 developmenttesting加了 production 还以为能绕过 disable_in_production
security.disable_in_production阻止生产和 staging 环境启用 Swagger。启动校验时。当前默认逻辑会强制它回到 true,即便 YAML 写 false只改这个字段就想在生产开放 Swagger。
security.trusted_origins控制 UI 服务的 CORS 允许来源。每次 UI 请求。默认只允许 localhost 来源。忘了把实际加载 Swagger UI 的浏览器来源加进去。
security.require_auth预期中的 UI 额外鉴权开关。启动时会解析。当前会存储,但 handler 并不真正执行鉴权。设成 true 就以为 UI 已经被保护。
api_server.host设置 Swagger UI “Try it out” 调用的目标 API host。启动和重建时。留空时会尝试读取 lynx.http.addr:80800.0.0.0:8080 会被改写成 localhost:8080留空后却没有可推导的 lynx.http.addr,或该地址浏览器根本不可达。
api_server.base_path设置 “Try it out” 的 Swagger basePath重建时。可选。继续填顶层 base_path,以为当前运行时会读。

当前已过时或无运行时效果的模板键

模板键当前运行时状态应该怎么理解 / 用什么替代常见误配
generator.exclude_dirs不会被消费。当前 generator 只保存 scan_dirs,模板里的排除逻辑还没接线。以为列了 vendor / docs 就会自动跳过。
generator.recursive不会被消费。目录扫描行为来自解析器实现,而不是这个 YAML 键。设成 false 还以为只会浅层扫描。
generator.watch_enabled不会被消费。真正的 watcher 开关是 generator.watch_files设成 false 后还在看到热更新。
generator.watch_interval不会被消费。当前 watcher 使用代码内固定默认值。调了它却看不到重建节奏变化。
generator.gen_on_startup不会被消费。当前只要 generator 启用,启动就会重建文档。设成 false 还以为启动会跳过生成。
ui.title不会被消费。应改 info.title;当前页面标题读的是后者。只改 ui.title
ui.spec_url不会被消费。当前 UI 会固定服务 path + "/doc.json"/swagger.json以为浏览器会跟着这个 URL 取文档。
ui.auto_refresh不会被消费。当前没有这项运行时支持。开了它却等不到自动刷新。
ui.refresh_interval不会被消费。当前没有这项运行时支持。调了它却没有任何浏览器刷新效果。
ui.deep_linkingsnake_case 不会被消费。需要时应改为 camelCase ui.deepLinking,当前 HTML 确实会渲染它。直接照抄 secure 模板后发现深链接没生效。
ui.display_request_duration当前 HTML 不会渲染。即便改成 camelCase 也只是存储,页面不会展示。期待 Swagger UI 显示请求耗时标签。
ui.doc_expansionsnake_case 不会被消费。需要时应改为 camelCase ui.docExpansion,当前 HTML 会渲染它。用 snake_case 去调展开策略。
ui.default_models_expand_depth当前 HTML 不会渲染。即便 camelCase 存储了,现有 renderer 也不用。期待模型树展开层级变化。
info.terms_of_servicesnake_case 不会被消费。当前结构体字段是 termsOfService填了模板键却发现 spec 里仍为空。
servers不会从 YAML 读取。当前插件只通过 api_server 设置 Host / BasePath在 YAML 里维护多环境 servers,却期待输出 spec 带上它们。
base_path不会从 YAML 读取。当前应使用 api_server.base_path两边都填,还以为顶层会覆盖。
schemes不会从 YAML 读取。基础 spec 当前由代码固定初始化 httphttps调整模板后却发现输出 spec 没变。
consumes不会从 YAML 读取。当前没有运行时映射。列了 media type 就以为输出 spec 会采用。
produces不会从 YAML 读取。当前没有运行时映射。同上。
tags不会从 YAML 读取。路由 tag 仍来自合并 spec 和注解解析。在这里维护标签描述,却期待 UI 自动展示。
external_docs不会从 YAML 读取。当前没有运行时映射。填了手册链接却在输出里看不到。
security_definitions不会从 YAML 读取。当前自定义配置结构没有这部分映射。以为模板里写了认证方案,生成文档就会自动包含。
顶层 Swagger security 要求不会从 YAML 读取。当前没有运行时映射。期待全局认证要求自动出现在生成文档里。
advanced.*不会从 YAML 读取。当前没有验证、pretty JSON、缓存、扫描并发等映射。调性能 / 缓存参数却看不到任何变化。

swagger-simple.yml

这个模板适合只保留最小工作面:

  • enabled
  • generator.enabled
  • generator.spec_files
  • generator.scan_dirs
  • generator.output_path
  • generator.watch_files,如果你希望显式控制 watcher
  • ui.enabled
  • ui.port
  • ui.path
  • info.title
  • info.version
  • info.description
  • api_server.host
  • api_server.base_path

模板里自带的 watch_enabled 是过时键;如果你想把 watcher 写明,请改成 watch_files

swagger.yml

完整版模板要拆成两部分理解:

  • 真正 live 的,仍然只是上面“当前运行时真正读取的键”那一批。
  • serversschemesconsumesproducestagsexternal_docssecurity_definitionssecurityadvanced 这些偏元数据 / 高级输出块,目前更像“愿景清单”,还不是会驱动现有运行时行为的键。

所以 swagger.yml 更适合当成能力库存,而不是“所有字段都能立刻生效”的现成运行时配置。

swagger-secure.yml

secure 模板是最容易直接误抄的一份:

  • security.environmentallowed_environmentsdisable_in_productiontrusted_origins 是 live 的。
  • require_auth 会被读取,但当前并不真正执行鉴权。
  • ui.deep_linkingui.display_request_durationui.doc_expansionui.default_models_expand_depth 都写成了 snake_case,而当前运行时结构体期望 camelCase。
  • generator.watch_enabledgenerator.watch_intervalgenerator.gen_on_startup 都是过时键。

如果你保留 swagger-secure.yml,应该把它当成“安全意图清单”,然后把真正被当前运行时理解的字段名改正后再使用。

完整 YAML 示例

下面这个示例把 swagger.ymlswagger-simple.ymlswagger-secure.yml 里的字段库存合并到了一个块里。当前运行时不会消费的模板键,会保留成注释形式,避免复制后误导成 live 配置。

lynx:
swagger:
enabled: true # 总开关;默认 true

security:
environment: "development" # 运行时环境标签
allowed_environments:
- "development" # 允许 Swagger 运行的环境
- "testing"
disable_in_production: true # 当前默认逻辑会强制它回到 true
trusted_origins:
- "http://localhost:8080" # UI 服务允许的浏览器来源
- "http://127.0.0.1:8081"
require_auth: false # 当前会存储,但 handler 不会真的执行鉴权

generator:
enabled: true # 注解扫描 / 重建开关
spec_files:
- "./openapi/openapi.yaml" # 扫描前先加载的外部 OAS 文件
scan_dirs:
- "./app/controllers" # 注解扫描目录
- "./app/handlers"
- "./plugins"
output_path: "./docs/swagger.json" # 合并后的输出路径
watch_files: true # 当前 live 的运行时键;模板里仍写 watch_enabled
# exclude_dirs: ["./vendor", "./test", "./docs", "./.git"] # 模板时代键;当前不消费
# recursive: true # 模板时代键;当前不消费
# watch_enabled: true # 模板时代键;当前应改用 watch_files
# watch_interval: 5s # 模板时代键;当前不消费
# gen_on_startup: true # 模板时代键;当前不消费

ui:
enabled: true # UI HTTP 服务开关
port: 8081 # UI 服务端口;默认 8081
path: "/swagger" # UI 路由前缀
deepLinking: true # 当前 HTML 真正会渲染的 camelCase 运行时键
docExpansion: "list" # 当前 HTML 真正会渲染的 camelCase 运行时键
# title: "Lynx API Documentation" # 模板时代键;当前页面标题来自 info.title
# spec_url: "/swagger.json" # 模板时代键;当前不消费
# auto_refresh: false # 模板时代键;当前不消费
# refresh_interval: 5000 # 模板时代键;当前不消费
# deep_linking: true # 模板 snake_case 键;当前运行时期望 deepLinking
# display_request_duration: true # 模板键;当前会存储但不会渲染
# doc_expansion: "list" # 模板 snake_case 键;当前运行时期望 docExpansion
# default_models_expand_depth: 1 # 模板键;当前 HTML 不会使用

info:
title: "Lynx Microservice API" # OpenAPI 标题,也是当前 HTML 页面的标题
description: "Secure API documentation built on Lynx framework" # OpenAPI 描述
version: "1.0.0" # API 版本号
termsOfService: "http://swagger.io/terms/" # 当前运行时使用的 camelCase 服务条款字段
contact:
name: "API Support Team" # 联系人名称
email: "api-support@lynx.io" # 联系邮箱
url: "https://lynx.io/support" # 联系链接
license:
name: "Apache 2.0" # 许可证名称
url: "http://www.apache.org/licenses/LICENSE-2.0.html" # 许可证链接
# terms_of_service: "http://swagger.io/terms/" # 模板 snake_case 键;当前不消费

api_server:
host: "localhost:8080" # Swagger UI “Try it out” 实际调用的目标 API 地址
base_path: "/api/v1" # “Try it out” 使用的 Swagger basePath

# servers: # 仅模板库存;当前运行时不会读取
# - url: "http://localhost:8080"
# description: "Development environment"
# base_path: "/api/v1" # 仅模板顶层键;当前应改用 api_server.base_path
# schemes: ["http", "https"] # 当前只是模板字段
# consumes: ["application/json", "application/xml", "multipart/form-data"] # 当前只是模板字段
# produces: ["application/json", "application/xml"] # 当前只是模板字段
# tags: # 当前只是模板字段
# - name: "User Management"
# description: "User-related operations"
# external_docs:
# description: "More information"
# url: "https://lynx.io/docs/user"
# external_docs: # 当前只是模板字段
# description: "Lynx Framework Documentation"
# url: "https://lynx.io/docs"
# security_definitions: # 当前只是模板字段
# api_key:
# type: "apiKey"
# name: "X-API-Key"
# in: "header"
# description: "API key authentication"
# security: # Swagger 顶层安全要求;当前只是模板字段
# - api_key: []
# advanced: # 当前只是模板字段
# validate_spec: true
# pretty_json: true
# include_unused_definitions: false
# generate_examples: true
# max_file_size: 10485760
# scan_concurrency: 4
# cache:
# enabled: true
# ttl: 300s
# max_size: 100

最小可用 YAML 示例

lynx:
swagger:
enabled: true # 总开关
generator:
enabled: true # 从代码生成文档
scan_dirs:
- "./" # swagger-simple.yml 里最小的扫描范围
output_path: "./docs/openapi.yaml" # 生成后的文档输出路径
ui:
enabled: true # 启动 Swagger UI 服务
port: 8081 # 避开 lynx-http 业务端口
path: "/swagger" # UI 路由
info:
title: "My API" # 页面标题和 OpenAPI 标题
version: "1.0.0" # OpenAPI 版本号
api_server:
host: "localhost:8080" # “Try it out” 指向的 lynx-http 地址

如果 lynx.http.addr 本身已经是浏览器可访问地址,也可以省略 api_server.host,让运行时自行推导。

实用规则

  • 想让 Swagger UI 调到正确后端,最好显式写 api_server.host,除非 lynx.http.addr 本身已经是浏览器可访问的地址。
  • 想在生产环境开放 Swagger,当前代码路径比模板暗示得更严格;默认逻辑仍会拦 production 和 staging。
  • 只要某个键来自旧 proto / 旧模板表面,正式依赖它前都应先确认 swagger.go 里是否真有对应字段。