validator package - github.com/pb33f/libopenapi-validator - Go Packages
This section is empty.
This section is empty.
This section is empty.
type Validator interface {
ValidateHttpRequest(request *http.Request) (bool, []*errors.ValidationError)
ValidateHttpRequestSync(request *http.Request) (bool, []*errors.ValidationError)
ValidateHttpRequestWithPathItem(request *http.Request, pathItem *v3.PathItem, pathValue string) (bool, []*errors.ValidationError)
ValidateHttpRequestSyncWithPathItem(request *http.Request, pathItem *v3.PathItem, pathValue string) (bool, []*errors.ValidationError)
ValidateHttpResponse(request *http.Request, response *http.Response) (bool, []*errors.ValidationError)
ValidateHttpRequestResponse(request *http.Request, response *http.Response) (bool, []*errors.ValidationError)
ValidateDocument() (bool, []*errors.ValidationError)
GetParameterValidator() parameters.ParameterValidator
GetRequestBodyValidator() requests.RequestBodyValidator
GetResponseBodyValidator() responses.ResponseBodyValidator
SetDocument(document libopenapi.Document)
}
Validator provides a coarse grained interface for validating an OpenAPI 3+ documents. There are three primary use-cases for validation
Validating *http.Request objects against and OpenAPI 3+ document Validating *http.Response objects against an OpenAPI 3+ document Validating an OpenAPI 3+ document against the OpenAPI 3+ specification
NewValidator will create a new Validator from an OpenAPI 3+ document
// 1. Load the OpenAPI 3+ spec into a byte array
petstore, err := os.ReadFile("test_specs/invalid_31.yaml")
if err != nil {
panic(err)
}
// 2. Create a new OpenAPI document using libopenapi
document, docErrs := libopenapi.NewDocument(petstore)
if docErrs != nil {
panic(docErrs)
}
// 3. Create a new validator
docValidator, validatorErrs := NewValidator(document)
if validatorErrs != nil {
panic(validatorErrs)
}
// 4. Validate!
valid, validationErrs := docValidator.ValidateDocument()
if !valid {
for i, e := range validationErrs {
// 5. Handle the error
fmt.Printf("%d: Type: %s, Failure: %s\n", i, e.ValidationType, e.Message)
fmt.Printf("Fix: %s\n\n", e.HowToFix)
}
}
Output: 0: Type: schema, Failure: Document does not pass validation Fix: Ensure that the object being submitted, matches the schema correctly
// 1. Load the OpenAPI 3+ spec into a byte array
petstore, err := os.ReadFile("test_specs/petstorev3.json")
if err != nil {
panic(err)
}
// 2. Create a new OpenAPI document using libopenapi
document, docErrs := libopenapi.NewDocument(petstore)
if docErrs != nil {
panic(docErrs)
}
// 3. Create a new validator
docValidator, validatorErrs := NewValidator(document)
if validatorErrs != nil {
panic(validatorErrs)
}
// 4. Create a new *http.Request (normally, this would be where the host application will pass in the request)
// Note: /pet/{petId} requires api_key OR petstore_auth (OAuth2). Since OAuth2 is not validated,
// the security check passes. The path parameter validation fails because "NotAValidPetId" is not an integer.
request, _ := http.NewRequest(http.MethodGet, "/pet/NotAValidPetId", nil)
// 5. Validate!
valid, validationErrs := docValidator.ValidateHttpRequest(request)
if !valid {
for _, e := range validationErrs {
// 5. Handle the error
fmt.Printf("Type: %s, Failure: %s\n", e.ValidationType, e.Message)
}
}
Output: Type: parameter, Failure: Path parameter 'petId' is not a valid integer
// 1. Load the OpenAPI 3+ spec into a byte array
petstore, err := os.ReadFile("test_specs/petstorev3.json")
if err != nil {
panic(err)
}
// 2. Create a new OpenAPI document using libopenapi
document, docErrs := libopenapi.NewDocument(petstore)
if docErrs != nil {
panic(docErrs)
}
// 3. Create a new validator
docValidator, validatorErrs := NewValidator(document)
if validatorErrs != nil {
panic(validatorErrs)
}
// 6. Create a new *http.Request (normally, this would be where the host application will pass in the request)
request, _ := http.NewRequest(http.MethodGet, "/pet/findByStatus?status=sold", nil)
// 7. Simulate a request/response, in this case the contract returns a 200 with an array of pets.
// Normally, this would be where the host application would pass in the response.
recorder := httptest.NewRecorder()
handler := func(w http.ResponseWriter, r *http.Request) {
// set return content type.
w.Header().Set(helpers.ContentTypeHeader, helpers.JSONContentType)
w.WriteHeader(http.StatusOK)
// create a Pet
body := map[string]interface{}{
"id": 123,
"name": "cotton",
"category": map[string]interface{}{
"id": "NotAValidPetId", // this will fail, it should be an integer.
"name": "dogs",
},
"photoUrls": []string{"https://pb33f.io"},
}
// marshal the request body into bytes.
responseBodyBytes, _ := json.Marshal([]interface{}{body}) // operation returns an array of pets
// return the response.
_, _ = w.Write(responseBodyBytes)
}
// simulate request/response
handler(recorder, request)
// 7. Validate!
valid, validationErrs := docValidator.ValidateHttpRequestResponse(request, recorder.Result())
if !valid {
for _, e := range validationErrs {
// 5. Handle the error
fmt.Printf("Type: %s, Failure: %s\n", e.ValidationType, e.Message)
fmt.Printf("Schema Error: %s, Line: %d, Col: %d\n",
e.SchemaValidationErrors[0].Reason,
e.SchemaValidationErrors[0].Line,
e.SchemaValidationErrors[0].Column)
}
}
Output: Type: response, Failure: 200 response body for '/pet/findByStatus' failed to validate schema Schema Error: got string, want integer, Line: 19, Col: 27
// 1. Load the OpenAPI 3+ spec into a byte array
petstore, err := os.ReadFile("test_specs/petstorev3.json")
if err != nil {
panic(err)
}
// 2. Create a new OpenAPI document using libopenapi
document, docErrs := libopenapi.NewDocument(petstore)
if docErrs != nil {
panic(docErrs)
}
// 3. Create a new validator
docValidator, validatorErrs := NewValidator(document)
if validatorErrs != nil {
panic(validatorErrs)
}
// 4. Create a new *http.Request (normally, this would be where the host application will pass in the request)
request, _ := http.NewRequest(http.MethodGet, "/pet/NotAValidPetId", nil)
// 5. Validate!
valid, validationErrs := docValidator.ValidateHttpRequestSync(request)
if !valid {
for _, e := range validationErrs {
// 5. Handle the error
fmt.Printf("Type: %s, Failure: %s\n", e.ValidationType, e.Message)
}
}
Output: Type: parameter, Failure: Path parameter 'petId' is not a valid integer
// 1. Load the OpenAPI 3+ spec into a byte array
petstore, err := os.ReadFile("test_specs/petstorev3.json")
if err != nil {
panic(err)
}
// 2. Create a new OpenAPI document using libopenapi
document, docErrs := libopenapi.NewDocument(petstore)
if docErrs != nil {
panic(docErrs)
}
// 3. Create a new validator
docValidator, validatorErrs := NewValidator(document)
if validatorErrs != nil {
panic(validatorErrs)
}
// 6. Create a new *http.Request (normally, this would be where the host application will pass in the request)
request, _ := http.NewRequest(http.MethodGet, "/pet/findByStatus?status=sold", nil)
// 7. Simulate a request/response, in this case the contract returns a 200 with an array of pets.
// Normally, this would be where the host application would pass in the response.
recorder := httptest.NewRecorder()
handler := func(w http.ResponseWriter, r *http.Request) {
// set return content type.
w.Header().Set(helpers.ContentTypeHeader, helpers.JSONContentType)
w.WriteHeader(http.StatusOK)
// create a Pet
body := map[string]interface{}{
"id": 123,
"name": "cotton",
"category": map[string]interface{}{
"id": "NotAValidPetId", // this will fail, it should be an integer.
"name": "dogs",
},
"photoUrls": []string{"https://pb33f.io"},
}
// marshal the request body into bytes.
responseBodyBytes, _ := json.Marshal([]interface{}{body}) // operation returns an array of pets
// return the response.
_, _ = w.Write(responseBodyBytes)
}
// simulate request/response
handler(recorder, request)
// 7. Validate the response only
valid, validationErrs := docValidator.ValidateHttpResponse(request, recorder.Result())
if !valid {
for _, e := range validationErrs {
// 5. Handle the error
fmt.Printf("Type: %s, Failure: %s\n", e.ValidationType, e.Message)
fmt.Printf("Schema Error: %s, Line: %d, Col: %d\n",
e.SchemaValidationErrors[0].Reason,
e.SchemaValidationErrors[0].Line,
e.SchemaValidationErrors[0].Column)
}
}
Output: Type: response, Failure: 200 response body for '/pet/findByStatus' failed to validate schema Schema Error: got string, want integer, Line: 19, Col: 27
NewValidatorFromV3Model will create a new Validator from an OpenAPI Model