Release Notes v1.21.0

Adds general-purpose OpenAPI 3 spec diffing to the openapi3 package, plus a matching oas3diff CLI. Compare two specs across endpoints, operation IDs, and schema names to spot version drift, verify a migration lost no coverage, or measure what a newer spec adds. This is an additive, backward-compatible release.

Highlights

  • Spec diffing (openapi3.SpecsDiff): report the endpoints, operation IDs, and schema names unique to each of two specs, and those shared.
  • Rename-aware endpoint comparison: endpoints are compared generically (path variables normalized), so an operationId rename does not hide the fact that the same endpoint exists in both specs.
  • oas3diff CLI: diff two specs (JSON or YAML) from the command line.

New Features

openapi3.SpecMetadataDiff

The diff is modeled as the complement of the existing Intersection API, reusing SpecMetadata{Endpoints, OperationIDs, SchemaNames}.

package main

import (
    "fmt"

    "github.com/grokify/spectrum/openapi3"
)

func main() {
    // Reads JSON or YAML.
    diff, err := openapi3.ReadSpecsDiff("v1.json", "v2.yaml", false)
    if err != nil {
        panic(err)
    }

    fmt.Print(diff.String())

    // Or drive it programmatically:
    //   d := openapi3.SpecsDiff(spec1, spec2)
    //   d.OnlyInSpec1.Endpoints  // endpoints only in spec 1 (lost coverage)
    //   d.OnlyInSpec2.SchemaNames // schemas only in spec 2 (added)
    //   d.Both.OperationIDs       // shared operation IDs
    if diff.IsEmpty() {
        fmt.Println("specs are equivalent across all dimensions")
    }
}

API surface:

Symbol Purpose
SpecsDiff(spec1, spec2 *Spec) SpecMetadataDiff Diff two parsed specs.
ReadSpecsDiff(file1, file2 string, validate bool) Read (JSON or YAML) and diff.
SpecMetadata.Diff(md2) SpecMetadataDiff Three-way compare (only-in-1, only-in-2, both).
SpecMetadata.Difference(md2) SpecMetadata Set-minus per dimension.
SpecMetadataDiff.String() / IsEmpty() / Sort() Report and inspect.

Endpoints are the generic path method strings from SpecMore.PathMethods(true), so parameter-name and operationId renames never create false differences.

oas3diff CLI

go install github.com/grokify/spectrum/cmd/oas3diff@latest

oas3diff spec-v1.json spec-v2.yaml
Endpoints: 9 in both, 1 only in spec 1, 60 only in spec 2
  - only in spec 1: /products/{}/releases/{} PUT
  + only in spec 2: /epics GET
  + only in spec 2: /goals GET
  ...
OperationIDs: ...
SchemaNames: ...

Upgrade

Purely additive — no existing exported signature changed or was removed. Upgrade with:

go get github.com/grokify/spectrum@v1.21.0

See the CHANGELOG for the full list of changes.