loopbackio / loopbackio/loopback-next
example or examples keywords in jsonSchema is causing ajv validation to fail
- Dominant language
- TypeScript
- Stars
- 5.1k
- Forks
- 1.1k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 27
Description
## Steps to reproduce
Define a model w/ property values samples expressed in jsonSchema as follow :
`import {Entity, model, property} from '@loopback/repository';
@model()
export class Basic extends Entity {
@property({
jsonSchema: {
type: 'string',
example: 'simple',
// examples: [{'simple-sample': {value: 'simple'}}],
},
required: true,
})
name: string;
@property({
type: 'string',
id: true,
generated: true,
})
id?: string;
constructor(data?: Partial) {
super(data);
}
}
export interface BasicRelations {
// describe navigational properties here
}
export type BasicWithRelations = Basic & BasicRelations;`
Reference this entity as the request body in a route :
` @post('/basics')
@response(200, {
description: 'Basic model instance',
content: {'application/json': {schema: getModelSchemaRef(Basic)}},
})
async create(
@requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Basic, {
title: 'NewBasic',
}),
},
},
})
basic: Basic,
): Promise {
return this.basicRepository.create(basic);
}`
## Current Behavior
Ajv validation fail when trying to call the route
w/ DEBUG='loopback:rest:validation'
` BasicController
loopback:rest:validation Request body schema: { '$ref': '#/components/schemas/NewBasic' } +0ms
loopback:rest:validation referencing: {
title: 'NewBasic',
type: 'object',
description: "(tsType: Basic, schemaOptions: { title: 'NewBasic' })",
properties: {
name: { type: 'string', example: 'simple' },
id: { type: 'string' }
},
required: [ 'name' ],
additionalProperties: false,
'x-typescript-type': 'Basic'
} +1ms
loopback:rest:validation Converted OpenAPI schema to JSON schema: { '$ref': '#/components/schemas/NewBasic' } +102ms
Request POST /basics failed with status code 500. Error: strict mode: unknown keyword: "example"
at checkStrictMode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/util.ts:211:28)
at checkUnknownRules (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/util.ts:27:22)
at Object.alwaysValidSchema (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/util.ts:17:3)
at /home/fgeslin/simple-lb4-app/node_modules/ajv/lib/vocabularies/applicator/properties.ts:23:48
at Array.filter ()
at Object.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/vocabularies/applicator/properties.ts:23:33)
at keywordCode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:523:9)
at /home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:265:9
at CodeGen.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:525:33)
at CodeGen.block (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:680:20)
at iterateKeywords (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:262:7)
at groupKeywords (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:241:7)
at /home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:233:38
at CodeGen.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:525:33)
at CodeGen.block (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:680:20)
at schemaKeywords (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:232:7)
at typeAndKeywords (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:161:3)
at subSchemaObjCode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:147:3)
at subschemaCode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:124:7)
at KeywordCxt.subschema (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:491:5)
at inlineRefSchema (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/vocabularies/core/ref.ts:40:26)
at Object.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/vocabularies/core/ref.ts:21:12)
at keywordCode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:523:9)
at /home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:228:21
at CodeGen.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:525:33)
at CodeGen.block (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:680:20)
at schemaKeywords (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:228:9)
at typeAndKeywords (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:161:3)
at /home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:100:5
at CodeGen.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:525:33)
at /home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:61:45
at CodeGen.code (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:525:33)
at CodeGen.func (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/codegen/index.ts:699:24)
at validateFunction (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:60:9)
at topSchemaObjCode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:94:3)
at Object.validateFunctionCode (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/validate/index.ts:42:7)
at Ajv.compileSchema (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/compile/index.ts:163:5)
at Ajv._compileSchemaEnv (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/core.ts:718:24)
at Ajv.compile (/home/fgeslin/simple-lb4-app/node_modules/ajv/lib/core.ts:370:34)
at createValidator (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/validation/request-body.validator.ts:235:18)
at validateValueAgainstSchema (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/validation/request-body.validator.ts:150:16)
at Object.validateRequestBody (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/validation/request-body.validator.ts:76:9)
at buildOperationArguments (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/parser.ts:92:9)
at Object.parseOperationArgs (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/parser.ts:48:10)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at /home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/providers/parse-params.provider.ts:68:22
at /home/fgeslin/simple-lb4-app/node_modules/@loopback/express/src/middleware-interceptor.ts:131:19
at /home/fgeslin/simple-lb4-app/node_modules/@loopback/express/src/middleware-interceptor.ts:131:19
at /home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/providers/send.provider.ts:46:24
at MySequence.handle (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/sequence.ts:291:5)
at HttpHandler._handleRequest (/home/fgeslin/simple-lb4-app/node_modules/@loopback/rest/src/http-handler.ts:115:5)
1) invokes POST /basics
`
## Expected Behavior
Ajv validation OK
## Link to reproduction sandbox
n/a
## Additional information
## Related Issues
n/a
_See [Reporting Issues](http://loopback.io/doc/en/contrib/Reporting-issues.html) for more tips on writing good issues_
Contributor guide
Research direction
Start at @loopback/rest/src/validation/request-body.validator.ts and trace the request-body schema conversion into AJV, using the Basic model and POST /basics reproduction described here. Check how the OpenAPI schema's example and examples keywords are handled, then verify the POST request succeeds with AJV validation enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100