Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre Fenoll <[email protected]>
  • Loading branch information
fenollp committed May 31, 2021
1 parent 93b7798 commit 6d81fa8
Show file tree
Hide file tree
Showing 16 changed files with 324 additions and 989 deletions.
45 changes: 10 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,44 +155,19 @@ func xmlBodyDecoder(body []byte) (interface{}, error) {
}
```

## Custom function to check uniqueness of array items

By defaut, the library check unique items by below predefined function

```go
func isSliceOfUniqueItems(xs []interface{}) bool {
s := len(xs)
m := make(map[string]struct{}, s)
for _, x := range xs {
key, _ := json.Marshal(&x)
m[string(key)] = struct{}{}
}
return s == len(m)
}
```

In the predefined function using `json.Marshal` to generate a string can
be used as a map key which is to support check the uniqueness of an array
when the array items are objects or arrays. You can register
you own function according to your input data to get better performance:

```go
func main() {
// ...

// Register a customized function used to check uniqueness of array.
openapi3.RegisterArrayUniqueItemsChecker(arrayUniqueItemsChecker)

// ... other validate codes
}

func arrayUniqueItemsChecker(items []interface{}) bool {
// Check the uniqueness of the input slice
}
```

## Sub-v0 breaking API changes

### v0.???
OpenAPIv3 "in-house" schema validation was replaced with a correct JSON Schema implementation and conversion from OpenAPIv3 Schema to JSON Schema.
* Dropped `openapi3.ErrOneOfConflict`: now when a value matches more than one `oneOf` schemas the error string contains `Must validate one and only one schema (oneOf)`
* Dropped `openapi3.SchemaFormatValidationDisabled`: any `openapi3.Schema.Format` value is valid.
* Dropped `openapi3.FailFast() openapi3.SchemaValidationOption` and `openapi3.SchemaErrorDetailsDisabled`: validating values against schemas is offloaded to a third-party library that does not provide such a mechanism.
* Dropped `openapi3.RegisterArrayUniqueItemsChecker(openapi3.SliceUniqueItemsChecker)`: validating values against schemas is offloaded to a third-party library that does not provide such a mechanism.
* Dropped `openapi3.SchemaStringFormats`, `openapi3.FormatCallback`, `openapi3.Format`, `openapi3.FormatOfStringForUUIDOfRFC4122`, `openapi3.DefineStringFormat(...)` and `openapi3.DefineStringFormatCallback(...)`. If your special format is not already under [`gojsonschema.FormatCheckers`](https://pkg.go.dev/github.com/xeipuuv/gojsonschema#pkg-variables), first define a [`gojsonschema.FormatChecker`](https://pkg.go.dev/github.com/xeipuuv/gojsonschema#FormatChecker) and register it with [`gojsonschema.FormatCheckers.Add("my-format", myImpl{})`](https://pkg.go.dev/github.com/xeipuuv/gojsonschema#FormatCheckerChain.Add) *before compiling your schemas*.
* Dropped `openapi3.ErrSchemaInputNaN` and `openapi3.ErrSchemaInputInf`: OpenAPIv3 does not explicitly mention the related values.
* Replaced `openapi3.SchemaError` with `openapi3.SchemaValidationError` which wraps `[]gojsonschema.ResultError` and thus provides similar functionality and more.

### v0.61.0
* Renamed `openapi2.Swagger` to `openapi2.T`.
* Renamed `openapi2conv.FromV3Swagger` to `openapi2conv.FromV3`.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ require (
github.com/go-openapi/jsonpointer v0.19.5
github.com/gorilla/mux v1.8.0
github.com/stretchr/testify v1.5.1
github.com/xeipuuv/gojsonschema v1.2.0
gopkg.in/yaml.v2 v2.3.0 // indirect
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
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=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
38 changes: 38 additions & 0 deletions openapi3/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,46 @@ package openapi3
import (
"bytes"
"errors"
"strings"

"github.com/xeipuuv/gojsonschema"
)

// SchemaValidationError is a collection of errors
type SchemaValidationError []gojsonschema.ResultError

var _ error = (*SchemaValidationError)(nil)

func (e SchemaValidationError) Error() string {
var buff strings.Builder
for i, re := range []gojsonschema.ResultError(e) {
if i != 0 {
buff.WriteString("\n")
}
buff.WriteString(re.String())
}
return buff.String()
}

// Errors unwraps into much detailed errors.
// See https://pkg.go.dev/github.com/xeipuuv/gojsonschema#ResultError
func (e SchemaValidationError) Errors() []gojsonschema.ResultError {
return e
}

// JSONPointer returns a dot (.) delimited "JSON path" to the context of the first error.
func (e SchemaValidationError) JSONPointer() string {
return []gojsonschema.ResultError(e)[0].Field()
}

func (e SchemaValidationError) asMultiError() MultiError {
errs := make([]error, 0, len(e))
for _, re := range e {
errs = append(errs, errors.New(re.String()))
}
return errs
}

// MultiError is a collection of errors, intended for when
// multiple issues need to be reported upstream
type MultiError []error
Expand Down
41 changes: 41 additions & 0 deletions openapi3/openapi3.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"

"github.com/getkin/kin-openapi/jsoninfo"
"github.com/xeipuuv/gojsonschema"
)

// T is the root of an OpenAPI v3 document
Expand All @@ -19,6 +20,46 @@ type T struct {
Servers Servers `json:"servers,omitempty" yaml:"servers,omitempty"`
Tags Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`

refd, refdAsReq, refdAsRep *gojsonschema.SchemaLoader
}

// CompileSchemas needs to be called before any use of VisitJSON*()
func (doc *T) CompileSchemas() error {
if err := doc.compileSchemas(newSchemaValidationSettings(VisitAsRequest())); err != nil {
return err
}
if err := doc.compileSchemas(newSchemaValidationSettings(VisitAsResponse())); err != nil {
return err
}
return doc.compileSchemas(newSchemaValidationSettings())
}

func (doc *T) compileSchemas(settings *schemaValidationSettings) (err error) {
docSchemas := doc.Components.Schemas
schemas := make(schemasJSON, len(docSchemas))
for name, docSchema := range docSchemas {
schemas[name] = docSchema.Value.fromOpenAPISchema(settings)
}
//FIXME merge loops
refd := gojsonschema.NewSchemaLoader()
for name, schema := range schemas {
absRef := "#/components/schemas/" + name
sl := gojsonschema.NewGoLoader(schema)
if err = refd.AddSchema(absRef, sl); err != nil {
return
}
}

switch {
case settings.asreq:
doc.refdAsReq = refd
case settings.asrep:
doc.refdAsRep = refd
default:
doc.refd = refd
}
return
}

func (doc *T) MarshalJSON() ([]byte, error) {
Expand Down
Loading

0 comments on commit 6d81fa8

Please sign in to comment.