Skip to content

Commit

Permalink
Enables jsonpointer support in openapi3 (#276)
Browse files Browse the repository at this point in the history
  • Loading branch information
gordallott committed Dec 8, 2020
1 parent e8b3436 commit 9b9280d
Show file tree
Hide file tree
Showing 17 changed files with 761 additions and 53 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.14

require (
github.com/ghodss/yaml v1.0.0
github.com/go-openapi/jsonpointer v0.19.5
github.com/stretchr/testify v1.5.1
gopkg.in/yaml.v2 v2.3.0 // indirect
)
14 changes: 14 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
23 changes: 22 additions & 1 deletion openapi3/callback.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
package openapi3

import "context"
import (
"context"
"fmt"

"github.com/go-openapi/jsonpointer"
)

type Callbacks map[string]*CallbackRef

var _ jsonpointer.JSONPointable = (*Callbacks)(nil)

func (c Callbacks) JSONLookup(token string) (interface{}, error) {
ref, ok := c[token]
if ref == nil || ok == false {
return nil, fmt.Errorf("object has no field %q", token)
}

if ref.Ref != "" {
return &Ref{Ref: ref.Ref}, nil
}
return ref.Value, nil
}

// Callback is specified by OpenAPI/Swagger standard version 3.0.
type Callback map[string]*PathItem
Expand Down
18 changes: 9 additions & 9 deletions openapi3/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (
// Components is specified by OpenAPI/Swagger standard version 3.0.
type Components struct {
ExtensionProps
Schemas map[string]*SchemaRef `json:"schemas,omitempty" yaml:"schemas,omitempty"`
Parameters map[string]*ParameterRef `json:"parameters,omitempty" yaml:"parameters,omitempty"`
Headers map[string]*HeaderRef `json:"headers,omitempty" yaml:"headers,omitempty"`
RequestBodies map[string]*RequestBodyRef `json:"requestBodies,omitempty" yaml:"requestBodies,omitempty"`
Responses map[string]*ResponseRef `json:"responses,omitempty" yaml:"responses,omitempty"`
SecuritySchemes map[string]*SecuritySchemeRef `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
Examples map[string]*ExampleRef `json:"examples,omitempty" yaml:"examples,omitempty"`
Links map[string]*LinkRef `json:"links,omitempty" yaml:"links,omitempty"`
Callbacks map[string]*CallbackRef `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
Schemas Schemas `json:"schemas,omitempty" yaml:"schemas,omitempty"`
Parameters ParametersMap `json:"parameters,omitempty" yaml:"parameters,omitempty"`
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
RequestBodies RequestBodies `json:"requestBodies,omitempty" yaml:"requestBodies,omitempty"`
Responses Responses `json:"responses,omitempty" yaml:"responses,omitempty"`
SecuritySchemes SecuritySchemes `json:"securitySchemes,omitempty" yaml:"securitySchemes,omitempty"`
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
Links Links `json:"links,omitempty" yaml:"links,omitempty"`
Callbacks Callbacks `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
}

func NewComponents() Components {
Expand Down
10 changes: 5 additions & 5 deletions openapi3/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
type Encoding struct {
ExtensionProps

ContentType string `json:"contentType,omitempty" yaml:"contentType,omitempty"`
Headers map[string]*HeaderRef `json:"headers,omitempty" yaml:"headers,omitempty"`
Style string `json:"style,omitempty" yaml:"style,omitempty"`
Explode *bool `json:"explode,omitempty" yaml:"explode,omitempty"`
AllowReserved bool `json:"allowReserved,omitempty" yaml:"allowReserved,omitempty"`
ContentType string `json:"contentType,omitempty" yaml:"contentType,omitempty"`
Headers Headers `json:"headers,omitempty" yaml:"headers,omitempty"`
Style string `json:"style,omitempty" yaml:"style,omitempty"`
Explode *bool `json:"explode,omitempty" yaml:"explode,omitempty"`
AllowReserved bool `json:"allowReserved,omitempty" yaml:"allowReserved,omitempty"`
}

func NewEncoding() *Encoding {
Expand Down
19 changes: 19 additions & 0 deletions openapi3/examples.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
package openapi3

import (
"fmt"

"github.com/getkin/kin-openapi/jsoninfo"
"github.com/go-openapi/jsonpointer"
)

type Examples map[string]*ExampleRef

var _ jsonpointer.JSONPointable = (*Examples)(nil)

func (e Examples) JSONLookup(token string) (interface{}, error) {
ref, ok := e[token]
if ref == nil || ok == false {
return nil, fmt.Errorf("object has no field %q", token)
}

if ref.Ref != "" {
return &Ref{Ref: ref.Ref}, nil
}
return ref.Value, nil
}

// Example is specified by OpenAPI/Swagger 3.0 standard.
type Example struct {
ExtensionProps
Expand Down
61 changes: 54 additions & 7 deletions openapi3/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,43 @@ package openapi3

import (
"context"
"fmt"

"github.com/getkin/kin-openapi/jsoninfo"
"github.com/go-openapi/jsonpointer"
)

type Headers map[string]*HeaderRef

var _ jsonpointer.JSONPointable = (*Headers)(nil)

func (h Headers) JSONLookup(token string) (interface{}, error) {
ref, ok := h[token]
if ref == nil || ok == false {
return nil, fmt.Errorf("object has no field %q", token)
}

if ref.Ref != "" {
return &Ref{Ref: ref.Ref}, nil
}
return ref.Value, nil
}

type Header struct {
ExtensionProps

// Optional description. Should use CommonMark syntax.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Examples map[string]*ExampleRef `json:"examples,omitempty" yaml:"examples,omitempty"`
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
Required bool `json:"required,omitempty" yaml:"required,omitempty"`
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
Content Content `json:"content,omitempty" yaml:"content,omitempty"`
}

var _ jsonpointer.JSONPointable = (*Header)(nil)

func (value *Header) UnmarshalJSON(data []byte) error {
return jsoninfo.UnmarshalStrictStruct(data, value)
}
Expand All @@ -31,3 +51,30 @@ func (value *Header) Validate(c context.Context) error {
}
return nil
}

func (value Header) JSONLookup(token string) (interface{}, error) {
switch token {
case "schema":
if value.Schema != nil {
if value.Schema.Ref != "" {
return &Ref{Ref: value.Schema.Ref}, nil
}
return value.Schema.Value, nil
}
case "description":
return value.Description, nil
case "deprecated":
return value.Deprecated, nil
case "required":
return value.Required, nil
case "example":
return value.Example, nil
case "examples":
return value.Examples, nil
case "content":
return value.Content, nil
}

v, _, err := jsonpointer.GetForToken(value.ExtensionProps, token)
return v, err
}
17 changes: 17 additions & 0 deletions openapi3/link.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,25 @@ import (
"fmt"

"github.com/getkin/kin-openapi/jsoninfo"
"github.com/go-openapi/jsonpointer"
)

type Links map[string]*LinkRef

func (l Links) JSONLookup(token string) (interface{}, error) {
ref, ok := l[token]
if ok == false {
return nil, fmt.Errorf("object has no field %q", token)
}

if ref != nil && ref.Ref != "" {
return &Ref{Ref: ref.Ref}, nil
}
return ref.Value, nil
}

var _ jsonpointer.JSONPointable = (*Links)(nil)

// Link is specified by OpenAPI/Swagger standard version 3.0.
type Link struct {
ExtensionProps
Expand Down
31 changes: 27 additions & 4 deletions openapi3/media_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ import (
"context"

"github.com/getkin/kin-openapi/jsoninfo"
"github.com/go-openapi/jsonpointer"
)

// MediaType is specified by OpenAPI/Swagger 3.0 standard.
type MediaType struct {
ExtensionProps

Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Examples map[string]*ExampleRef `json:"examples,omitempty" yaml:"examples,omitempty"`
Encoding map[string]*Encoding `json:"encoding,omitempty" yaml:"encoding,omitempty"`
Schema *SchemaRef `json:"schema,omitempty" yaml:"schema,omitempty"`
Example interface{} `json:"example,omitempty" yaml:"example,omitempty"`
Examples Examples `json:"examples,omitempty" yaml:"examples,omitempty"`
Encoding map[string]*Encoding `json:"encoding,omitempty" yaml:"encoding,omitempty"`
}

var _ jsonpointer.JSONPointable = (*MediaType)(nil)

func NewMediaType() *MediaType {
return &MediaType{}
}
Expand Down Expand Up @@ -75,3 +78,23 @@ func (mediaType *MediaType) Validate(c context.Context) error {
}
return nil
}

func (mediaType MediaType) JSONLookup(token string) (interface{}, error) {
switch token {
case "schema":
if mediaType.Schema != nil {
if mediaType.Schema.Ref != "" {
return &Ref{Ref: mediaType.Schema.Ref}, nil
}
return mediaType.Schema.Value, nil
}
case "example":
return mediaType.Example, nil
case "examples":
return mediaType.Examples, nil
case "encoding":
return mediaType.Encoding, nil
}
v, _, err := jsonpointer.GetForToken(mediaType.ExtensionProps, token)
return v, err
}
42 changes: 41 additions & 1 deletion openapi3/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strconv"

"github.com/getkin/kin-openapi/jsoninfo"
"github.com/go-openapi/jsonpointer"
)

// Operation represents "operation" specified by" OpenAPI/Swagger 3.0 standard.
Expand Down Expand Up @@ -34,7 +35,7 @@ type Operation struct {
Responses Responses `json:"responses" yaml:"responses"` // Required

// Optional callbacks
Callbacks map[string]*CallbackRef `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`
Callbacks Callbacks `json:"callbacks,omitempty" yaml:"callbacks,omitempty"`

Deprecated bool `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`

Expand All @@ -47,6 +48,8 @@ type Operation struct {
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
}

var _ jsonpointer.JSONPointable = (*Operation)(nil)

func NewOperation() *Operation {
return &Operation{}
}
Expand All @@ -59,6 +62,43 @@ func (operation *Operation) UnmarshalJSON(data []byte) error {
return jsoninfo.UnmarshalStrictStruct(data, operation)
}

func (operation Operation) JSONLookup(token string) (interface{}, error) {
switch token {
case "requestBody":
if operation.RequestBody != nil {
if operation.RequestBody.Ref != "" {
return &Ref{Ref: operation.RequestBody.Ref}, nil
}
return operation.RequestBody.Value, nil
}
case "tags":
return operation.Tags, nil
case "summary":
return operation.Summary, nil
case "description":
return operation.Description, nil
case "operationID":
return operation.OperationID, nil
case "parameters":
return operation.Parameters, nil
case "responses":
return operation.Responses, nil
case "callbacks":
return operation.Callbacks, nil
case "deprecated":
return operation.Deprecated, nil
case "security":
return operation.Security, nil
case "servers":
return operation.Servers, nil
case "externalDocs":
return operation.ExternalDocs, nil
}

v, _, err := jsonpointer.GetForToken(operation.ExtensionProps, token)
return v, err
}

func (operation *Operation) AddParameter(p *Parameter) {
operation.Parameters = append(operation.Parameters, &ParameterRef{
Value: p,
Expand Down
Loading

0 comments on commit 9b9280d

Please sign in to comment.