Skip to content

Commit ba04a83

Browse files
authored
Merge pull request #8 from TykTechnologies/TT-16407/oas-3.1-community-pr
[TT-16407] OAS 3.1 Community PR
2 parents ff57f1d + 1793d0d commit ba04a83

29 files changed

+3338
-251
lines changed

.github/docs/openapi3.txt

Lines changed: 178 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,30 @@ package openapi3 // import "github.com/getkin/kin-openapi/openapi3"
22

33
Package openapi3 parses and writes OpenAPI 3 specification documents.
44

5-
See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md
5+
Supports both OpenAPI 3.0 and OpenAPI 3.1:
6+
- OpenAPI 3.0.x:
7+
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md
8+
- OpenAPI 3.1.x:
9+
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md
10+
11+
OpenAPI 3.1 Features:
12+
- Type arrays with null support (e.g., ["string", "null"])
13+
- JSON Schema 2020-12 keywords (const, examples, prefixItems, etc.)
14+
- Webhooks for defining callback operations
15+
- JSON Schema dialect specification
16+
- SPDX license identifiers
17+
18+
The implementation maintains 100% backward compatibility with OpenAPI 3.0.
19+
20+
For OpenAPI 3.1 validation, use the JSON Schema 2020-12 validator option:
21+
22+
schema.VisitJSON(value, openapi3.EnableJSONSchema2020())
23+
24+
Version detection is available via helper methods:
25+
26+
if doc.IsOpenAPI3_1() {
27+
// Handle OpenAPI 3.1 specific features
28+
}
629

730
Code generated by go generate; DO NOT EDIT.
831

@@ -680,7 +703,8 @@ type Info struct {
680703
Extensions map[string]any `json:"-" yaml:"-"`
681704
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
682705

683-
Title string `json:"title" yaml:"title"` // Required
706+
Title string `json:"title" yaml:"title"` // Required
707+
Summary string `json:"summary,omitempty" yaml:"summary,omitempty"` // OpenAPI 3.1
684708
Description string `json:"description,omitempty" yaml:"description,omitempty"`
685709
TermsOfService string `json:"termsOfService,omitempty" yaml:"termsOfService,omitempty"`
686710
Contact *Contact `json:"contact,omitempty" yaml:"contact,omitempty"`
@@ -689,6 +713,8 @@ type Info struct {
689713
}
690714
Info is specified by OpenAPI/Swagger standard version 3. See
691715
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#info-object
716+
and
717+
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#info-object
692718

693719
func (info Info) MarshalJSON() ([]byte, error)
694720
MarshalJSON returns the JSON encoding of Info.
@@ -711,9 +737,15 @@ type License struct {
711737

712738
Name string `json:"name" yaml:"name"` // Required
713739
URL string `json:"url,omitempty" yaml:"url,omitempty"`
740+
741+
// Identifier is an SPDX license expression for the API (OpenAPI 3.1)
742+
// Either url or identifier can be specified, not both
743+
Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"`
714744
}
715745
License is specified by OpenAPI/Swagger standard version 3. See
716746
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#license-object
747+
and
748+
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#license-object
717749

718750
func (license License) MarshalJSON() ([]byte, error)
719751
MarshalJSON returns the JSON encoding of License.
@@ -1611,6 +1643,19 @@ type Schema struct {
16111643
MaxProps *uint64 `json:"maxProperties,omitempty" yaml:"maxProperties,omitempty"`
16121644
AdditionalProperties AdditionalProperties `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"`
16131645
Discriminator *Discriminator `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`
1646+
1647+
// OpenAPI 3.1 / JSON Schema 2020-12 fields
1648+
Const any `json:"const,omitempty" yaml:"const,omitempty"`
1649+
Examples []any `json:"examples,omitempty" yaml:"examples,omitempty"`
1650+
PrefixItems []*SchemaRef `json:"prefixItems,omitempty" yaml:"prefixItems,omitempty"`
1651+
Contains *SchemaRef `json:"contains,omitempty" yaml:"contains,omitempty"`
1652+
MinContains *uint64 `json:"minContains,omitempty" yaml:"minContains,omitempty"`
1653+
MaxContains *uint64 `json:"maxContains,omitempty" yaml:"maxContains,omitempty"`
1654+
PatternProperties Schemas `json:"patternProperties,omitempty" yaml:"patternProperties,omitempty"`
1655+
DependentSchemas Schemas `json:"dependentSchemas,omitempty" yaml:"dependentSchemas,omitempty"`
1656+
PropertyNames *SchemaRef `json:"propertyNames,omitempty" yaml:"propertyNames,omitempty"`
1657+
UnevaluatedItems *SchemaRef `json:"unevaluatedItems,omitempty" yaml:"unevaluatedItems,omitempty"`
1658+
UnevaluatedProperties *SchemaRef `json:"unevaluatedProperties,omitempty" yaml:"unevaluatedProperties,omitempty"`
16141659
}
16151660
Schema is specified by OpenAPI/Swagger 3.0 standard. See
16161661
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schema-object
@@ -1847,6 +1892,12 @@ func EnableFormatValidation() SchemaValidationOption
18471892
validating documents that mention schema formats that are not defined by the
18481893
OpenAPIv3 specification.
18491894

1895+
func EnableJSONSchema2020() SchemaValidationOption
1896+
EnableJSONSchema2020 enables JSON Schema 2020-12 compliant validation.
1897+
This enables support for OpenAPI 3.1 and JSON Schema 2020-12 features.
1898+
When enabled, validation uses the jsonschema library instead of the built-in
1899+
validator.
1900+
18501901
func FailFast() SchemaValidationOption
18511902
FailFast returns schema validation errors quicker.
18521903

@@ -2102,10 +2153,20 @@ type T struct {
21022153
Tags Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
21032154
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
21042155

2156+
// OpenAPI 3.1.x specific fields
2157+
// Webhooks are a new feature in OpenAPI 3.1 that allow APIs to define callback operations
2158+
Webhooks map[string]*PathItem `json:"webhooks,omitempty" yaml:"webhooks,omitempty"`
2159+
2160+
// JSONSchemaDialect allows specifying the default JSON Schema dialect for Schema Objects
2161+
// See https://spec.openapis.org/oas/v3.1.0#schema-object
2162+
JSONSchemaDialect string `json:"jsonSchemaDialect,omitempty" yaml:"jsonSchemaDialect,omitempty"`
2163+
21052164
// Has unexported fields.
21062165
}
21072166
T is the root of an OpenAPI v3 document See
21082167
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#openapi-object
2168+
and
2169+
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#openapi-object
21092170

21102171
func (doc *T) AddOperation(path string, method string, operation *Operation)
21112172

@@ -2126,6 +2187,12 @@ func (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, Comp
21262187

21272188
doc.InternalizeRefs(context.Background(), nil)
21282189

2190+
func (doc *T) IsOpenAPI3_0() bool
2191+
IsOpenAPI3_0 returns true if the document is OpenAPI 3.0.x
2192+
2193+
func (doc *T) IsOpenAPI3_1() bool
2194+
IsOpenAPI3_1 returns true if the document is OpenAPI 3.1.x
2195+
21292196
func (doc *T) JSONLookup(token string) (any, error)
21302197
JSONLookup implements
21312198
https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
@@ -2143,6 +2210,9 @@ func (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error
21432210
Validate returns an error if T does not comply with the OpenAPI spec.
21442211
Validations Options can be provided to modify the validation behavior.
21452212

2213+
func (doc *T) Version() string
2214+
Version returns the major.minor version of the OpenAPI document
2215+
21462216
type Tag struct {
21472217
Extensions map[string]any `json:"-" yaml:"-"`
21482218
Origin *Origin `json:"__origin__,omitempty" yaml:"__origin__,omitempty"`
@@ -2175,18 +2245,124 @@ func (tags Tags) Validate(ctx context.Context, opts ...ValidationOption) error
21752245
Validate returns an error if Tags does not comply with the OpenAPI spec.
21762246

21772247
type Types []string
2248+
Types represents the type(s) of a schema.
2249+
2250+
In OpenAPI 3.0, this is typically a single type (e.g., "string"). In OpenAPI
2251+
3.1, it can be an array of types (e.g., ["string", "null"]).
2252+
2253+
Serialization behavior:
2254+
- Single type: serializes as a string (e.g., "string")
2255+
- Multiple types: serializes as an array (e.g., ["string", "null"])
2256+
- Accepts both string and array formats when unmarshaling
2257+
2258+
Example OpenAPI 3.0 (single type):
2259+
2260+
schema := &Schema{Type: &Types{"string"}}
2261+
// JSON: {"type": "string"}
2262+
2263+
Example OpenAPI 3.1 (type array):
2264+
2265+
schema := &Schema{Type: &Types{"string", "null"}}
2266+
// JSON: {"type": ["string", "null"]}
21782267

21792268
func (pTypes *Types) Includes(typ string) bool
2269+
Includes returns true if the given type is included in the type array.
2270+
Returns false if types is nil.
2271+
2272+
Example:
2273+
2274+
types := &Types{"string", "null"}
2275+
types.Includes("string") // true
2276+
types.Includes("null") // true
2277+
types.Includes("number") // false
2278+
2279+
func (types *Types) IncludesNull() bool
2280+
IncludesNull returns true if the type array includes "null". This is useful
2281+
for OpenAPI 3.1 where null is a first-class type.
2282+
2283+
Example:
2284+
2285+
types := &Types{"string", "null"}
2286+
types.IncludesNull() // true
2287+
2288+
types = &Types{"string"}
2289+
types.IncludesNull() // false
21802290

21812291
func (types *Types) Is(typ string) bool
2292+
Is returns true if the schema has exactly one type and it matches the given
2293+
type. This is useful for OpenAPI 3.0 style single-type checks.
2294+
2295+
Example:
2296+
2297+
types := &Types{"string"}
2298+
types.Is("string") // true
2299+
types.Is("number") // false
2300+
2301+
types = &Types{"string", "null"}
2302+
types.Is("string") // false (multiple types)
2303+
2304+
func (types *Types) IsEmpty() bool
2305+
IsEmpty returns true if no types are specified (nil or empty array).
2306+
When a schema has no type specified, it permits any type.
2307+
2308+
Example:
2309+
2310+
var nilTypes *Types
2311+
nilTypes.IsEmpty() // true
2312+
2313+
types := &Types{}
2314+
types.IsEmpty() // true
2315+
2316+
types = &Types{"string"}
2317+
types.IsEmpty() // false
2318+
2319+
func (types *Types) IsMultiple() bool
2320+
IsMultiple returns true if multiple types are specified. This is an OpenAPI
2321+
3.1 feature that enables type arrays.
2322+
2323+
Example:
2324+
2325+
types := &Types{"string"}
2326+
types.IsMultiple() // false
2327+
2328+
types = &Types{"string", "null"}
2329+
types.IsMultiple() // true
2330+
2331+
func (types *Types) IsSingle() bool
2332+
IsSingle returns true if exactly one type is specified.
2333+
2334+
Example:
2335+
2336+
types := &Types{"string"}
2337+
types.IsSingle() // true
2338+
2339+
types = &Types{"string", "null"}
2340+
types.IsSingle() // false
21822341

21832342
func (pTypes *Types) MarshalJSON() ([]byte, error)
21842343

21852344
func (pTypes *Types) MarshalYAML() (any, error)
21862345

21872346
func (types *Types) Permits(typ string) bool
2347+
Permits returns true if the given type is permitted. Returns true if types
2348+
is nil (any type allowed), otherwise checks if the type is included.
2349+
2350+
Example:
2351+
2352+
var nilTypes *Types
2353+
nilTypes.Permits("anything") // true (nil permits everything)
2354+
2355+
types := &Types{"string"}
2356+
types.Permits("string") // true
2357+
types.Permits("number") // false
21882358

21892359
func (types *Types) Slice() []string
2360+
Slice returns the types as a string slice. Returns nil if types is nil.
2361+
2362+
Example:
2363+
2364+
types := &Types{"string", "null"}
2365+
slice := types.Slice() // []string{"string", "null"}
21902366

21912367
func (types *Types) UnmarshalJSON(data []byte) error
21922368

.github/workflows/ci-tests.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Run tests
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
9+
env:
10+
TIMEOUT: 20m
11+
BRANCH_NAME: ${{ github.base_ref || github.ref_name }} # base_ref for PRs is 'master', but merges read in ref_name
12+
13+
jobs:
14+
lint:
15+
runs-on: ubuntu-latest
16+
if: ${{ !github.event.pull_request.draft }}
17+
steps:
18+
- name: "Checkout PR"
19+
uses: TykTechnologies/github-actions/.github/actions/checkout-pr@main
20+
with:
21+
token: ${{ secrets.ORG_GH_TOKEN }}
22+
23+
- name: "Get base ref"
24+
run: |
25+
git fetch origin ${{ env.BRANCH_NAME }}
26+
git rev-parse origin/${{ env.BRANCH_NAME }}
27+
28+
- name: Setup Golang
29+
uses: actions/setup-go@v5
30+
with:
31+
go-version-file: go.mod
32+
cache-dependency-path: go.sum
33+
34+
- name: golangci-lint
35+
uses: golangci/golangci-lint-action@v8
36+
timeout-minutes: 20
37+
with:
38+
version: v2.8.0
39+
only-new-issues: ${{ github.event_name == 'pull_request' }}
40+
# Output formats configured in .golangci.yml (v2 approach)
41+
# Generates: text to stdout + checkstyle JSON for SonarQube
42+
args: -v ./...
43+
skip-cache: false
44+
skip-save-cache: false
45+
46+
- uses: actions/upload-artifact@v4
47+
if: ${{ always() }}
48+
with:
49+
name: golangcilint
50+
retention-days: 1
51+
path: |
52+
golangci-lint-report.json
53+
54+
unit-tests:
55+
runs-on: ubuntu-latest
56+
outputs:
57+
latest-version: ${{ steps.get-latest-version.outputs.version }}
58+
steps:
59+
- name: Checkout Code
60+
uses: actions/checkout@v4
61+
with:
62+
ref: ${{ github.event.pull_request.head.ref }}
63+
64+
- name: Setup Golang
65+
uses: actions/setup-go@v5
66+
with:
67+
go-version: 1.24.x
68+
69+
- name: Run unit tests
70+
env:
71+
GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72+
run: go test ./...

0 commit comments

Comments
 (0)