github.com/swaggest/openapi-goを使ってOpenAPIを生成する
github.com/swaggest/openapi-goを使うとGoのコードからOpenAPIの定義(json/yaml)を生成できる。
例:
package main import ( "encoding/json" "fmt" "log" openapi "github.com/swaggest/openapi-go" "github.com/swaggest/openapi-go/openapi3" ) type endpoint struct { id string method string path string request any responses []response } type response struct { status int body any } func main() { r := openapi3.Reflector{ Spec: &openapi3.Spec{ Openapi: "3.0.3", Components: &openapi3.Components{}, }, } r.Spec.Info. WithTitle("Foo API"). WithDescription("Foo API Document."). WithVersion("1.0") list := []endpoint{ { id: "PostFoo", method: "POST", path: "/foo", request: new(PostFooRequest), responses: []response{ {status: 201, body: new(Foo)}, {status: 400, body: new(ErrorResponse)}, }, }, { id: "GetFoo", method: "GET", path: "/foo/{id}", request: new(GetFooRequest), responses: []response{ {status: 200, body: new(Foo)}, {status: 404, body: new(ErrorResponse)}, }, }, } for _, v := range list { oc, err := r.NewOperationContext(v.method, v.path) if err != nil { log.Println(err) continue } oc.SetID(v.id) oc.AddReqStructure(v.request) for _, resp := range v.responses { oc.AddRespStructure(resp.body, openapi.WithHTTPStatus(resp.status)) } if err := r.AddOperation(oc); err != nil { log.Println(err) continue } } // b, err := r.Spec.MarshalYAML() b, err := json.MarshalIndent(r.Spec, "", " ") if err != nil { log.Println(err) return } fmt.Println(string(b)) } type PostFooRequest struct { Data string `json:"data"` } type GetFooRequest struct { ID string `json:"id" path:"id"` } type Foo struct { ID string `json:"id"` Data string `json:"data"` } type ErrorResponse struct { Code string `json:"code"` Message string `json:"message"` }
list
の中身を既存コードから生成すれば途中からでも比較的簡単にOpenAPIを始められる。