From be7a8cfd8d3fc4b8f139adf49fdebacc55561c6c Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Tue, 9 Dec 2025 13:56:41 +0100 Subject: [PATCH] Add support for OpenAPI 3 Signed-off-by: Nicolas De Loof --- go.mod | 2 ++ spec.go | 30 +++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index bc0673c..94502c8 100644 --- a/go.mod +++ b/go.mod @@ -30,3 +30,5 @@ require ( ) go 1.24.0 + +replace github.com/go-openapi/spec => ../spec \ No newline at end of file diff --git a/spec.go b/spec.go index 51aab9d..e176c89 100644 --- a/spec.go +++ b/spec.go @@ -98,13 +98,6 @@ func Spec(path string, opts ...LoaderOption) (*Document, error) { // Analyzed creates a new analyzed spec document for a root json.RawMessage. func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*Document, error) { - if version == "" { - version = "2.0" - } - if version != "2.0" { - return nil, fmt.Errorf("spec version %q is not supported: %w", version, ErrLoads) - } - raw, err := trimData(data) // trim blanks, then convert yaml docs into json if err != nil { return nil, err @@ -120,9 +113,24 @@ func Analyzed(data json.RawMessage, version string, options ...LoaderOption) (*D return nil, errors.Join(err, ErrLoads) } + // Auto-detect spec version and select appropriate schema + var schema *spec.Schema + if swspec.Swagger == "2.0" { + // Swagger 2.0 spec + schema = spec.MustLoadSwagger20Schema() + } else if swspec.OpenAPI != "" { + // OpenAPI 3.x spec + schema = spec.MustLoadOpenAPI32Schema() + } else if version == "2.0" || version == "" { + // Default to Swagger 2.0 for backward compatibility + schema = spec.MustLoadSwagger20Schema() + } else { + schema = spec.MustLoadOpenAPI32Schema() + } + d := &Document{ Analyzer: analysis.New(swspec), // NOTE: at this moment, analysis does not follow $refs to documents outside the root doc - schema: spec.MustLoadSwagger20Schema(), + schema: schema, spec: swspec, raw: raw, origSpec: origsqspec, @@ -208,8 +216,12 @@ func (d *Document) BasePath() string { return d.spec.BasePath } -// Version returns the OpenAPI version of this spec (e.g. 2.0). +// Version returns the OpenAPI version of this spec (e.g. 2.0 or 3.0.0 for OpenAPI). func (d *Document) Version() string { + // Check OpenAPI v3 version first + if d.spec.OpenAPI != "" { + return d.spec.OpenAPI + } return d.spec.Swagger }