Skip to content

Commit 6d81fa8

Browse files
committed
wip
Signed-off-by: Pierre Fenoll <[email protected]>
1 parent 93b7798 commit 6d81fa8

16 files changed

+324
-989
lines changed

README.md

+10-35
Original file line numberDiff line numberDiff line change
@@ -155,44 +155,19 @@ func xmlBodyDecoder(body []byte) (interface{}, error) {
155155
}
156156
```
157157

158-
## Custom function to check uniqueness of array items
159-
160-
By defaut, the library check unique items by below predefined function
161-
162-
```go
163-
func isSliceOfUniqueItems(xs []interface{}) bool {
164-
s := len(xs)
165-
m := make(map[string]struct{}, s)
166-
for _, x := range xs {
167-
key, _ := json.Marshal(&x)
168-
m[string(key)] = struct{}{}
169-
}
170-
return s == len(m)
171-
}
172-
```
173-
174-
In the predefined function using `json.Marshal` to generate a string can
175-
be used as a map key which is to support check the uniqueness of an array
176-
when the array items are objects or arrays. You can register
177-
you own function according to your input data to get better performance:
178-
179-
```go
180-
func main() {
181-
// ...
182-
183-
// Register a customized function used to check uniqueness of array.
184-
openapi3.RegisterArrayUniqueItemsChecker(arrayUniqueItemsChecker)
185-
186-
// ... other validate codes
187-
}
188-
189-
func arrayUniqueItemsChecker(items []interface{}) bool {
190-
// Check the uniqueness of the input slice
191-
}
192-
```
193158

194159
## Sub-v0 breaking API changes
195160

161+
### v0.???
162+
OpenAPIv3 "in-house" schema validation was replaced with a correct JSON Schema implementation and conversion from OpenAPIv3 Schema to JSON Schema.
163+
* 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)`
164+
* Dropped `openapi3.SchemaFormatValidationDisabled`: any `openapi3.Schema.Format` value is valid.
165+
* 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.
166+
* Dropped `openapi3.RegisterArrayUniqueItemsChecker(openapi3.SliceUniqueItemsChecker)`: validating values against schemas is offloaded to a third-party library that does not provide such a mechanism.
167+
* 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*.
168+
* Dropped `openapi3.ErrSchemaInputNaN` and `openapi3.ErrSchemaInputInf`: OpenAPIv3 does not explicitly mention the related values.
169+
* Replaced `openapi3.SchemaError` with `openapi3.SchemaValidationError` which wraps `[]gojsonschema.ResultError` and thus provides similar functionality and more.
170+
196171
### v0.61.0
197172
* Renamed `openapi2.Swagger` to `openapi2.T`.
198173
* Renamed `openapi2conv.FromV3Swagger` to `openapi2conv.FromV3`.

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ require (
77
github.com/go-openapi/jsonpointer v0.19.5
88
github.com/gorilla/mux v1.8.0
99
github.com/stretchr/testify v1.5.1
10+
github.com/xeipuuv/gojsonschema v1.2.0
1011
gopkg.in/yaml.v2 v2.3.0 // indirect
1112
)

go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
2323
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
2424
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
2525
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
26+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
27+
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
28+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
29+
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
30+
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
31+
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
2632
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2733
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
2834
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

openapi3/errors.go

+38
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,46 @@ package openapi3
33
import (
44
"bytes"
55
"errors"
6+
"strings"
7+
8+
"github.com/xeipuuv/gojsonschema"
69
)
710

11+
// SchemaValidationError is a collection of errors
12+
type SchemaValidationError []gojsonschema.ResultError
13+
14+
var _ error = (*SchemaValidationError)(nil)
15+
16+
func (e SchemaValidationError) Error() string {
17+
var buff strings.Builder
18+
for i, re := range []gojsonschema.ResultError(e) {
19+
if i != 0 {
20+
buff.WriteString("\n")
21+
}
22+
buff.WriteString(re.String())
23+
}
24+
return buff.String()
25+
}
26+
27+
// Errors unwraps into much detailed errors.
28+
// See https://pkg.go.dev/github.com/xeipuuv/gojsonschema#ResultError
29+
func (e SchemaValidationError) Errors() []gojsonschema.ResultError {
30+
return e
31+
}
32+
33+
// JSONPointer returns a dot (.) delimited "JSON path" to the context of the first error.
34+
func (e SchemaValidationError) JSONPointer() string {
35+
return []gojsonschema.ResultError(e)[0].Field()
36+
}
37+
38+
func (e SchemaValidationError) asMultiError() MultiError {
39+
errs := make([]error, 0, len(e))
40+
for _, re := range e {
41+
errs = append(errs, errors.New(re.String()))
42+
}
43+
return errs
44+
}
45+
846
// MultiError is a collection of errors, intended for when
947
// multiple issues need to be reported upstream
1048
type MultiError []error

openapi3/openapi3.go

+41
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77

88
"github.com/getkin/kin-openapi/jsoninfo"
9+
"github.com/xeipuuv/gojsonschema"
910
)
1011

1112
// T is the root of an OpenAPI v3 document
@@ -19,6 +20,46 @@ type T struct {
1920
Servers Servers `json:"servers,omitempty" yaml:"servers,omitempty"`
2021
Tags Tags `json:"tags,omitempty" yaml:"tags,omitempty"`
2122
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"`
23+
24+
refd, refdAsReq, refdAsRep *gojsonschema.SchemaLoader
25+
}
26+
27+
// CompileSchemas needs to be called before any use of VisitJSON*()
28+
func (doc *T) CompileSchemas() error {
29+
if err := doc.compileSchemas(newSchemaValidationSettings(VisitAsRequest())); err != nil {
30+
return err
31+
}
32+
if err := doc.compileSchemas(newSchemaValidationSettings(VisitAsResponse())); err != nil {
33+
return err
34+
}
35+
return doc.compileSchemas(newSchemaValidationSettings())
36+
}
37+
38+
func (doc *T) compileSchemas(settings *schemaValidationSettings) (err error) {
39+
docSchemas := doc.Components.Schemas
40+
schemas := make(schemasJSON, len(docSchemas))
41+
for name, docSchema := range docSchemas {
42+
schemas[name] = docSchema.Value.fromOpenAPISchema(settings)
43+
}
44+
//FIXME merge loops
45+
refd := gojsonschema.NewSchemaLoader()
46+
for name, schema := range schemas {
47+
absRef := "#/components/schemas/" + name
48+
sl := gojsonschema.NewGoLoader(schema)
49+
if err = refd.AddSchema(absRef, sl); err != nil {
50+
return
51+
}
52+
}
53+
54+
switch {
55+
case settings.asreq:
56+
doc.refdAsReq = refd
57+
case settings.asrep:
58+
doc.refdAsRep = refd
59+
default:
60+
doc.refd = refd
61+
}
62+
return
2263
}
2364

2465
func (doc *T) MarshalJSON() ([]byte, error) {

0 commit comments

Comments
 (0)