-
-
Couldn't load subscription status.
- Fork 229
Description
Describe the bug
When response validation is enabled, and my spec contains several examples with a field called id containing the same string value, the express-openapi-validator in version 5.2.0 produces an unexpected error. This is not the case for request validation.
OpenAPI examples are removed from the apiDoc before request validation, but not before response validation. Some weird behavior in ajv seems to trigger the error when compiling the schema.
It probably makes sense to remove examples before response validation as well.
To Reproduce
Use the following OpenAPI spec with version 5.2.0 of theexpress-openapi-validator (this isn't a problem in 4.8.x):
openapi: '3.0.0'
info:
version: 1.0.0
title: Validation Error
description: A test spec that triggers an validation error on identical id fields in examples.
servers:
- url: http://{base_url}/{env_id}
variables:
base_url:
default: my.app.com
description: server
env_id:
default: v1
description: path selector
paths:
/ping:
post:
description: |
ping then pong!
operationId: ping
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Response"
examples:
response1:
summary: "Response 1"
value:
id: 'Some_ID'
message: 'Message 1'
response2:
summary: "Response 2"
value:
id: 'Some_ID'
message: 'Message 2'
components:
schemas:
Response:
required:
- id
- message
properties:
id:
type: string
message:
type: string
Invoke response validation as follows:
const apiSpec = path.join(__dirname, 'openapi.yml');
app.use(
OpenApiValidator.middleware({
apiSpec,
validateResponses: true
}),
);
Setting validateResponse to false and validateRequest to true will not produce the error.
Actual behavior
the express-openapi-validator produces the following error:
Error Message: "reference \"Some_ID\" resolves to more than one schema" (for full stack trace, see below)
Expected behavior
Validation of the response, without producing the described error.
Examples and context
Version of express-openapi-validator: 5.2.0
It seems like ajv currently suffers from a compatibility issue regarding properties named id, where the id property is used to differentiate JSON schemas generated by avj. If a property id only defines a new sub-schema, this is no problem. However, when populated with a concrete string value, two schemas having the same value will collide during compilation, resulting in the following error when validating responses:
"error": {
"message": "reference \"<ID_STRING>\" resolves to more than one schema",
"stack": [
"Error: reference \"<ID_STRING>\" resolves to more than one schema",
" at ambiguos (/Users/usr/project/node_modules/ajv/lib/compile/resolve.ts:147:12)",
" at Ajv.addRef (/Users/usr/project/node_modules/ajv/lib/compile/resolve.ts:115:38)",
" at /Users/usr/project/node_modules/ajv/lib/compile/resolve.ts:106:59",
" at _traverse (/Users/usr/project/node_modules/json-schema-traverse/index.js:69:5)",
" at _traverse (/Users/usr/project/node_modules/json-schema-traverse/index.js:83:9)",
" at _traverse (/Users/usr/project/node_modules/json-schema-traverse/index.js:83:9)",
" at _traverse (/Users/usr/project/node_modules/json-schema-traverse/index.js:83:9)",
" at _traverse (/Users/usr/project/node_modules/json-schema-traverse/index.js:83:9)",
" at _traverse (/Users/usr/project/node_modules/json-schema-traverse/index.js:83:9)",
" at module.exports (/Users/usr/project/node_modules/json-schema-traverse/index.js:14:3)",
" at Ajv.getSchemaRefs (/Users/usr/project/node_modules/ajv/lib/compile/resolve.ts:102:3)",
" at Ajv._addSchema (/Users/usr/project/node_modules/ajv/lib/core.ts:713:37)",
" at Ajv.compile (/Users/usr/project/node_modules/ajv/lib/core.ts:384:22)",
" at ResponseValidator.buildValidators (/Users/usr/project/node_modules/@xxx/api-validation/node_modules/express-openapi-validator/src/middlewares/openapi.response.validator.ts:302:8)",
" at ResponseValidator._getOrBuildValidator (/Users/usr/project/node_modules/@xxx/api-validation/node_modules/express-openapi-validator/src/middlewares/openapi.response.validator.ts:113:12)",
" at /Users/usr/project/node_modules/@xxx/api-validation/node_modules/express-openapi-validator/src/middlewares/openapi.response.validator.ts:64:26",
]
}
Luckily, it is rather rare that schema properties are defined with a fixed string. However, this is not true for schema examples. In our case, we had several examples using the same value for a property called id. This resulted in the above error when performing response validation, but not request validation. Digging in the code, it turns out examples are actually removed from the generated schema in the RequestValidator, but not for the ResponseValidator (see this line in the RequestValidator vs this function in the ResponseValidator).
As examples should never matter in the validation of responses, we suggest to remove examples in this case as well. In fact, probably removing the examples earlier, e.g., in this function, would be a good idea, if there is no use case I am missing.
If desired, I can create a pull request for this, but I am not sure if I will be able to take all edge cases into account.