package openapi import ( "encoding/json" "os" "path/filepath" "github.com/swaggest/openapi-go/openapi3" "gopkg.in/yaml.v3" ) // Generator OpenAPI 文档生成器 type Generator struct { Reflector *openapi3.Reflector } // NewGenerator 创建一个新的生成器实例 func NewGenerator(title, version string) *Generator { reflector := openapi3.Reflector{} reflector.Spec = &openapi3.Spec{ Openapi: "3.0.3", Info: openapi3.Info{ Title: title, Version: version, }, } return &Generator{Reflector: &reflector} } // AddOperation 向 OpenAPI 规范中添加一个操作 func (g *Generator) AddOperation(method, path, summary string, input interface{}, output interface{}, tags ...string) { op := openapi3.Operation{ Summary: &summary, Tags: tags, } // 反射输入 (请求参数/Body) if input != nil { // SetRequest 根据结构体标签自动检测 Body、Query 或 Path 参数 if err := g.Reflector.SetRequest(&op, input, method); err != nil { panic(err) // 生成过程中出错直接 panic,以便快速发现问题 } } // 反射输出 (响应 Body) if output != nil { if err := g.Reflector.SetJSONResponse(&op, output, 200); err != nil { panic(err) } } // 将操作添加到规范中 if err := g.Reflector.Spec.AddOperation(method, path, op); err != nil { panic(err) } } // Save 将规范导出为 YAML 文件 func (g *Generator) Save(filename string) error { // 确保目录存在 dir := filepath.Dir(filename) if err := os.MkdirAll(dir, 0755); err != nil { return err } // 安全的方法:MarshalJSON -> Unmarshal -> MarshalYAML // 这确保了我们遵守 openapi3 库中定义的 `json` 标签 jsonBytes, err := g.Reflector.Spec.MarshalJSON() if err != nil { return err } var obj interface{} if err := json.Unmarshal(jsonBytes, &obj); err != nil { return err } yamlBytes, err := yaml.Marshal(obj) if err != nil { return err } return os.WriteFile(filename, yamlBytes, 0644) }