Skip to content

Commit 6740cd2

Browse files
authored
openapi3: add support for extensions on the few types left (#763)
1 parent f6d1b8c commit 6740cd2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1213
-330
lines changed

.github/docs/openapi3.txt

Lines changed: 134 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,46 @@ func (addProps AdditionalProperties) MarshalJSON() ([]byte, error)
136136
func (addProps *AdditionalProperties) UnmarshalJSON(data []byte) error
137137
UnmarshalJSON sets AdditionalProperties to a copy of data.
138138

139-
type Callback map[string]*PathItem
139+
type Callback struct {
140+
Extensions map[string]interface{} `json:"-" yaml:"-"`
141+
142+
// Has unexported fields.
143+
}
140144
Callback is specified by OpenAPI/Swagger standard version 3. See
141145
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object
142146

143-
func (callback Callback) Validate(ctx context.Context, opts ...ValidationOption) error
147+
func NewCallback(opts ...NewCallbackOption) *Callback
148+
NewCallback builds a Callback object with path items in insertion order.
149+
150+
func NewCallbackWithCapacity(cap int) *Callback
151+
NewCallbackWithCapacity builds a Callback object of the given capacity.
152+
153+
func (callback Callback) JSONLookup(token string) (interface{}, error)
154+
JSONLookup implements
155+
https://github.com/go-openapi/jsonpointer#JSONPointable
156+
157+
func (callback *Callback) Len() int
158+
Len returns the amount of keys in callback excluding callback.Extensions.
159+
160+
func (callback *Callback) Map() map[string]*PathItem
161+
Map returns callback as a 'map'. Note: iteration on Go maps is not ordered.
162+
163+
func (callback Callback) MarshalJSON() ([]byte, error)
164+
MarshalJSON returns the JSON encoding of Callback.
165+
166+
func (callback *Callback) Set(key string, value *PathItem)
167+
Set adds or replaces key 'key' of 'callback' with 'value'. Note: 'callback'
168+
MUST be non-nil
169+
170+
func (callback *Callback) UnmarshalJSON(data []byte) (err error)
171+
UnmarshalJSON sets Callback to a copy of data.
172+
173+
func (callback *Callback) Validate(ctx context.Context, opts ...ValidationOption) error
144174
Validate returns an error if Callback does not comply with the OpenAPI spec.
145175

176+
func (callback *Callback) Value(key string) *PathItem
177+
Value returns the callback for key or nil
178+
146179
type CallbackRef struct {
147180
Ref string
148181
Value *Callback
@@ -609,6 +642,27 @@ func (me MultiError) Is(target error) bool
609642
`errors.Is()` It will also return true if any of the contained errors match
610643
target
611644

645+
type NewCallbackOption func(*Callback)
646+
NewCallbackOption describes options to NewCallback func
647+
648+
func WithCallback(cb string, pathItem *PathItem) NewCallbackOption
649+
WithCallback adds Callback as an option to NewCallback
650+
651+
type NewPathsOption func(*Paths)
652+
NewPathsOption describes options to NewPaths func
653+
654+
func WithPath(path string, pathItem *PathItem) NewPathsOption
655+
WithPath adds a named path item
656+
657+
type NewResponsesOption func(*Responses)
658+
NewResponsesOption describes options to NewResponses func
659+
660+
func WithName(name string, response *Response) NewResponsesOption
661+
WithName adds a name-keyed Response
662+
663+
func WithStatus(status int, responseRef *ResponseRef) NewResponsesOption
664+
WithStatus adds a status code keyed ResponseRef
665+
612666
type OAuthFlow struct {
613667
Extensions map[string]interface{} `json:"-" yaml:"-"`
614668

@@ -673,7 +727,7 @@ type Operation struct {
673727
RequestBody *RequestBodyRef `json:"requestBody,omitempty" yaml:"requestBody,omitempty"`
674728

675729
// Responses.
676-
Responses Responses `json:"responses" yaml:"responses"` // Required
730+
Responses *Responses `json:"responses" yaml:"responses"` // Required
677731

678732
// Optional callbacks
679733
Callbacks Callbacks `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
@@ -847,11 +901,21 @@ func (pathItem *PathItem) UnmarshalJSON(data []byte) error
847901
func (pathItem *PathItem) Validate(ctx context.Context, opts ...ValidationOption) error
848902
Validate returns an error if PathItem does not comply with the OpenAPI spec.
849903

850-
type Paths map[string]*PathItem
904+
type Paths struct {
905+
Extensions map[string]interface{} `json:"-" yaml:"-"`
906+
907+
// Has unexported fields.
908+
}
851909
Paths is specified by OpenAPI/Swagger standard version 3. See
852910
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object
853911

854-
func (paths Paths) Find(key string) *PathItem
912+
func NewPaths(opts ...NewPathsOption) *Paths
913+
NewPaths builds a paths object with path items in insertion order.
914+
915+
func NewPathsWithCapacity(cap int) *Paths
916+
NewPathsWithCapacity builds a paths object of the given capacity.
917+
918+
func (paths *Paths) Find(key string) *PathItem
855919
Find returns a path that matches the key.
856920

857921
The method ignores differences in template variable names (except possible
@@ -866,16 +930,39 @@ func (paths Paths) Find(key string) *PathItem
866930

867931
would return the correct path item.
868932

869-
func (paths Paths) InMatchingOrder() []string
933+
func (paths *Paths) InMatchingOrder() []string
870934
InMatchingOrder returns paths in the
871935
order they are matched against URLs. See
872936
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object
873937
When matching URLs, concrete (non-templated) paths would be matched before
874938
their templated counterparts.
875939

876-
func (paths Paths) Validate(ctx context.Context, opts ...ValidationOption) error
940+
func (paths Paths) JSONLookup(token string) (interface{}, error)
941+
JSONLookup implements
942+
https://github.com/go-openapi/jsonpointer#JSONPointable
943+
944+
func (paths *Paths) Len() int
945+
Len returns the amount of keys in paths excluding paths.Extensions.
946+
947+
func (paths *Paths) Map() map[string]*PathItem
948+
Map returns paths as a 'map'. Note: iteration on Go maps is not ordered.
949+
950+
func (paths Paths) MarshalJSON() ([]byte, error)
951+
MarshalJSON returns the JSON encoding of Paths.
952+
953+
func (paths *Paths) Set(key string, value *PathItem)
954+
Set adds or replaces key 'key' of 'paths' with 'value'. Note: 'paths' MUST
955+
be non-nil
956+
957+
func (paths *Paths) UnmarshalJSON(data []byte) (err error)
958+
UnmarshalJSON sets Paths to a copy of data.
959+
960+
func (paths *Paths) Validate(ctx context.Context, opts ...ValidationOption) error
877961
Validate returns an error if Paths does not comply with the OpenAPI spec.
878962

963+
func (paths *Paths) Value(key string) *PathItem
964+
Value returns the paths for key or nil
965+
879966
type ReadFromURIFunc func(loader *Loader, url *url.URL) ([]byte, error)
880967
ReadFromURIFunc defines a function which reads the contents of a resource
881968
located at a URI.
@@ -1039,28 +1126,58 @@ func (x *ResponseRef) Validate(ctx context.Context, opts ...ValidationOption) er
10391126
Validate returns an error if ResponseRef does not comply with the OpenAPI
10401127
spec.
10411128

1042-
type Responses map[string]*ResponseRef
1129+
type Responses struct {
1130+
Extensions map[string]interface{} `json:"-" yaml:"-"`
1131+
1132+
// Has unexported fields.
1133+
}
10431134
Responses is specified by OpenAPI/Swagger 3.0 standard. See
10441135
https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responses-object
10451136

1046-
func NewResponses() Responses
1137+
func NewResponses(opts ...NewResponsesOption) *Responses
1138+
NewResponses builds a responses object with response objects in insertion
1139+
order. Given no arguments, NewResponses returns a valid responses object
1140+
containing a default match-all reponse.
10471141

1048-
func (responses Responses) Default() *ResponseRef
1142+
func NewResponsesWithCapacity(cap int) *Responses
1143+
NewResponsesWithCapacity builds a responses object of the given capacity.
10491144

1050-
func (responses Responses) Get(status int) *ResponseRef
1051-
Get returns a ResponseRef for the given status If an exact
1145+
func (responses *Responses) Default() *ResponseRef
1146+
Default returns the default response
1147+
1148+
func (responses Responses) JSONLookup(token string) (interface{}, error)
1149+
JSONLookup implements
1150+
https://github.com/go-openapi/jsonpointer#JSONPointable
1151+
1152+
func (responses *Responses) Len() int
1153+
Len returns the amount of keys in responses excluding responses.Extensions.
1154+
1155+
func (responses *Responses) Map() map[string]*ResponseRef
1156+
Map returns responses as a 'map'. Note: iteration on Go maps is not ordered.
1157+
1158+
func (responses Responses) MarshalJSON() ([]byte, error)
1159+
MarshalJSON returns the JSON encoding of Responses.
1160+
1161+
func (responses *Responses) Set(key string, value *ResponseRef)
1162+
Set adds or replaces key 'key' of 'responses' with 'value'. Note:
1163+
'responses' MUST be non-nil
1164+
1165+
func (responses *Responses) Status(status int) *ResponseRef
1166+
Status returns a ResponseRef for the given status If an exact
10521167
match isn't initially found a patterned field is checked using
10531168
the first digit to determine the range (eg: 201 to 2XX) See
10541169
https://spec.openapis.org/oas/v3.0.3#patterned-fields-0
10551170

1056-
func (responses Responses) JSONLookup(token string) (interface{}, error)
1057-
JSONLookup implements
1058-
https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
1171+
func (responses *Responses) UnmarshalJSON(data []byte) (err error)
1172+
UnmarshalJSON sets Responses to a copy of data.
10591173

1060-
func (responses Responses) Validate(ctx context.Context, opts ...ValidationOption) error
1174+
func (responses *Responses) Validate(ctx context.Context, opts ...ValidationOption) error
10611175
Validate returns an error if Responses does not comply with the OpenAPI
10621176
spec.
10631177

1178+
func (responses *Responses) Value(key string) *ResponseRef
1179+
Value returns the responses for key or nil
1180+
10641181
type Schema struct {
10651182
Extensions map[string]interface{} `json:"-" yaml:"-"`
10661183

@@ -1519,7 +1636,7 @@ type T struct {
15191636
OpenAPI string `json:"openapi" yaml:"openapi"` // Required
15201637
Components *Components `json:"components,omitempty" yaml:"components,omitempty"`
15211638
Info *Info `json:"info" yaml:"info"` // Required
1522-
Paths Paths `json:"paths" yaml:"paths"` // Required
1639+
Paths *Paths `json:"paths" yaml:"paths"` // Required
15231640
Security SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"`
15241641
Servers Servers `json:"servers,omitempty" yaml:"servers,omitempty"`
15251642
Tags Tags `json:"tags,omitempty" yaml:"tags,omitempty"`

.github/workflows/go.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ jobs:
5252

5353
- uses: actions/checkout@v2
5454

55-
- name: Check codegen
56-
run: |
57-
./refs.sh | tee openapi3/refs.go
58-
git --no-pager diff --exit-code
55+
- run: ./refs.sh | tee openapi3/refs.go
56+
- run: git --no-pager diff --exit-code
57+
58+
- run: ./maps.sh
59+
- run: git --no-pager diff --exit-code
5960

60-
- name: Check docsgen
61-
run: ./docs.sh
61+
- run: ./docs.sh
6262

6363
- run: go mod download && go mod tidy && go mod verify
6464
- run: git --no-pager diff --exit-code
@@ -119,7 +119,7 @@ jobs:
119119
- if: runner.os == 'Linux'
120120
name: Ensure non-pointer MarshalJSON
121121
run: |
122-
! git grep -InE 'func.+[*].+[)].MarshalJSON[(][)]'
122+
! git grep -InE 'func[^{}]+[*][^{}]+[)].MarshalJSON[(][)]'
123123
124124
- if: runner.os == 'Linux'
125125
name: Use `loader := NewLoader(); loader.Load ...`

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ go run github.com/getkin/kin-openapi/cmd/validate@latest [--circular] [--default
7171
Use `openapi3.Loader`, which resolves all references:
7272
```go
7373
loader := openapi3.NewLoader()
74-
doc, err := loader.LoadFromFile("swagger.json")
74+
doc, err := loader.LoadFromFile("my-openapi-spec.json")
7575
```
7676

7777
## Getting OpenAPI operation that matches request
@@ -275,7 +275,15 @@ func safeErrorMessage(err *openapi3.SchemaError) string {
275275

276276
This will change the schema validation errors to return only the `Reason` field, which is guaranteed to not include the original value.
277277

278-
## CHANGELOG: Sub-v0 breaking API changes
278+
## CHANGELOG: Sub-v1 breaking API changes
279+
280+
### v0.122.0
281+
* `Paths` field of `openapi3.T` is now a pointer
282+
* `Responses` field of `openapi3.Operation` is now a pointer
283+
* `openapi3.Paths` went from `map[string]*PathItem` to a struct with an `Extensions` field and methods: `Set`, `Value`, `Len`, `Map`, and `New*`.
284+
* `openapi3.Callback` went from `map[string]*PathItem` to a struct with an `Extensions` field and methods: `Set`, `Value`, `Len`, `Map`, and `New*`.
285+
* `openapi3.Responses` went from `map[string]*ResponseRef` to a struct with an `Extensions` field and methods: `Set`, `Value`, `Len`, `Map`, and `New*`.
286+
* `(openapi3.Responses).Get(int)` renamed to `(*openapi3.Responses).Status(int)`
279287

280288
### v0.121.0
281289
* Introduce `openapi3.RequestBodies` (an alias on `map[string]*openapi3.ResponseRef`) and use it in place of `openapi3.Responses` for field `openapi3.Components.Responses`.

0 commit comments

Comments
 (0)