Examples validation does not conform to OpenAPI 3.0 standard in case of required property marked as readOnly
Hey,
we noticed a bug in the examples validation today and created the following minimal reproducible example specification:
openapi: 3.0.1
info:
description: Test API
title: Test API
version: "1"
servers:
- description: Some backend server
url: https://some.backend.server
paths:
/v1/test:
post:
description: Test endpoint
requestBody:
content:
application/json:
schema:
type: object
properties:
ID:
$ref: '#/components/schemas/ID'
required:
- ID
example:
ID:
someOtherId: test
required: true
responses:
"200":
description: success
components:
schemas:
ID:
description: Some ID
properties:
someId:
type: string
readOnly: true
someOtherId:
type: string
required:
- someId
- someOtherId
type: object
According to the OpenAPI 3.0.0 specification, the readOnly field within the someId property of the ID schema should lead to the example not requiring the someId property, i.e.
readOnly: Declares the property as "read only". This means that it MAY be sent as part of a response but SHOULD NOT be sent as part of the request
Still, the validation fails with
invalid paths: invalid path /v1/test: invalid operation POST: invalid example: Error at "/someID/someId": property "someId" is missing
Although, according to the OpenAPI specification standard, the property should not be part of the request. Instead, adding the someId property to the example erroneously fixes the validation.
Your example is validated correctly by:
package openapi3_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/getkin/kin-openapi/openapi3"
)
func TestIssue1012(t *testing.T) {
spec := `
openapi: 3.0.1
info:
description: Test API
title: Test API
version: "1"
servers:
- description: Some backend server
url: https://some.backend.server
paths:
/v1/test:
post:
description: Test endpoint
requestBody:
content:
application/json:
schema:
type: object
properties:
ID:
$ref: '#/components/schemas/ID'
required:
- ID
example:
ID:
someOtherId: test
required: true
responses:
"200":
description: success
components:
schemas:
ID:
description: Some ID
properties:
someId:
type: string
readOnly: true
someOtherId:
type: string
required:
- someId
- someOtherId
type: object
`[1:]
sl := openapi3.NewLoader()
doc, err := sl.LoadFromData([]byte(spec))
require.NoError(t, err)
require.NotNil(t, doc.Paths)
err = doc.Validate(sl.Context, openapi3.EnableExamplesValidation())
require.NoError(t, err)
require.NotNil(t, doc.Paths)
}
There must have been some regression because it does fail with err = doc.Validate(sl.Context). When no option is passed, the ctx is empty so it is not validating as neither response not request somehow
Update: this issue starts happening with #692