-
-
Couldn't load subscription status.
- Fork 229
Description
Describe the bug
When a malformed polymorphic implementation is in an array, errors returned by express-open-api validator state that the object must implement all required properties of all polymorphic implementations despite the discriminating property being present.
Versions:
express-openapi-validator v4.13.2
express v4.17.1
Node.js v14.7.4
npm v6.14.4
To Reproduce
See examples - spec, express setup, and curl requests are all provided
Actual behavior
Errors do not take discriminator into account and return errors relating to all polymorphic object implementations
[
{
"path": ".body[0].poly1_prop",
"message": "should have required property 'poly1_prop'",
"errorCode": "required.openapi.validation"
},
{
"path": ".body[0].poly2_prop",
"message": "should have required property 'poly2_prop'",
"errorCode": "required.openapi.validation"
},
{
"path": ".body[0]",
"message": "should match exactly one schema in oneOf",
"errorCode": "oneOf.openapi.validation"
},
{
"path": ".body[1].poly1_prop",
"message": "should have required property 'poly1_prop'",
"errorCode": "required.openapi.validation"
},
{
"path": ".body[1].poly2_prop",
"message": "should have required property 'poly2_prop'",
"errorCode": "required.openapi.validation"
},
{
"path": ".body[1]",
"message": "should match exactly one schema in oneOf",
"errorCode": "oneOf.openapi.validation"
}
]
Expected behavior
When the two malformed polymorphic objects are in an array and have valid discriminators, the following errors should be returned:
[
{
"path": ".body[0].poly1_prop",
"message": "should have required property 'poly1_prop'",
"errorCode": "required.openapi.validation"
},
{
"path": ".body[1].poly2_prop",
"message": "should have required property 'poly2_prop'",
"errorCode": "required.openapi.validation"
}
]
Examples and context
Example spec:
info:
title: Example API
version: 0.1.0
servers:
- url: https://localhost:3030/
paths:
/single:
post:
description: Request
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PolyObject'
responses:
"200":
description: Response
content:
application/json:
schema:
type: object
$ref: "#/components/schemas/PolyObject"
/array:
post:
description: Request
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PolyObject'
responses:
"200":
description: Response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/PolyObject"
components:
schemas:
PolyObject:
type: object
discriminator:
propertyName: object_type
mapping:
PolyObject1: '#/components/schemas/PolyObject1'
PolyObject2: '#/components/schemas/PolyObject2'
oneOf:
- $ref: '#/components/schemas/PolyObject1'
- $ref: '#/components/schemas/PolyObject2'
PolyObjectBase:
type: object
required:
- object_type
- shared_prop
properties:
object_type:
type: string
enum:
- PolyObject1
- PolyObject2
shared_prop:
type: string
PolyObject1:
allOf:
- $ref: '#/components/schemas/PolyObjectBase'
- required:
- poly1_prop
- type: object
properties:
poly1_prop:
type: string
PolyObject2:
allOf:
- $ref: '#/components/schemas/PolyObjectBase'
- required:
- poly2_prop
- type: object
properties:
poly2_prop:
type: string
Example express server:
const OpenApiValidator = require('express-openapi-validator');
const express = require('express');
const app = express()
app.use(express.json())
app.use(
OpenApiValidator.middleware({
apiSpec: './spec.yaml',
validateResponses: true
})
)
app.post("/single", (req, res) => {
res.status(200).json(req.body)
})
app.post("/array", (req, res) => {
res.status(200).json(req.body)
})
app.use((e, req, res, next) => {
res.status(500).json(e.errors || { error: e.message })
})
app.listen(3030, () => { console.log("Sever started") })
Example curl requests:
#!/bin/bash
# PolyObject1 missing poly1_prop
# Expected error returned
curl -s --request POST \
--url http://localhost:3030/single \
--header 'content-type: application/json' \
--data-raw '{
"object_type": "PolyObject1",
"shared_prop": "shared_value"
}'
# PolyObject2 missing poly2_prop
# Expected error returned
curl -s --request POST \
--url http://localhost:3030/single \
--header 'content-type: application/json' \
--data-raw '{
"object_type": "PolyObject2",
"shared_prop": "shared_value"
}'
# PolyObject1 missing poly1_prop
# and
# PolyObject2 missing poly2_prop
# Unexpected errors returned
curl -s --request POST \
--url http://localhost:3030/array \
--header 'content-type: application/json' \
--data-raw '[
{
"object_type": "PolyObject1",
"shared_prop": "shared_value"
},
{
"object_type": "PolyObject2",
"shared_prop": "shared_value"
}
]'