英文:
Using complex schema with AJV
问题
我想在 Ajv 模式中重复使用对象属性,但它声称无法解析某些部分:
```javascript
const Ajv = require("ajv@8.11.0").default
const ajv = new Ajv({
strictSchema: false,
loadSchema: async (uri) => {
console.log(uri);
switch (uri) {
case "main":
return {
entity: { $ref: "entity" },
request: { $ref: "request" }
}
case "entity":
return {
type: "object",
properties: {
id: {type: "string"}
},
}
case "request":
return {
type: "object",
properties: {
id: {$ref: "main#/entity/properties/id"}
},
}
}
},
})
const validate = await ajv.compileAsync({
$ref: "main#/request"
})
validate({
id: "123"
})
产生错误:Error: AnySchema main is loaded but main#/entity/properties/id cannot be resolved
将 main#/entity/properties/id
替换为 entity#/properties/id
则可以正常工作。我漏掉了什么?
<details>
<summary>英文:</summary>
I'd like to reuse object properties in Ajv schema, but it claims that some part cannot be resolved:
const Ajv = require("ajv@8.11.0").default
const ajv = new Ajv({
strictSchema: false,
loadSchema: async (uri) => {
console.log(uri);
switch (uri) {
case "main":
return {
entity: { $ref: "entity" },
request: { $ref: "request" }
}
case "entity":
return {
type: "object",
properties: {
id: {type: "string"}
},
}
case "request":
return {
type: "object",
properties: {
id: {$ref: "main#/entity/properties/id"}
},
}
}
},
})
const validate = await ajv.compileAsync({
$ref: "main#/request"
})
validate({
id: "123"
})
produces error: `Error: AnySchema main is loaded but main#/entity/properties/id cannot be resolved`
while replacing `main#/entity/properties/id` with `entity#/properties/id` makes it work. What I am missing?
Live code: https://runkit.com/desofto/64a40e034daec80008a495b5
</details>
# 答案1
**得分**: 0
Your `main` schema is precisely this:
```js
{
entity: { $ref: "entity" },
request: { $ref: "request" }
}
The JSON Pointer #/entity/properties/id
doesn't resolve to a location within main
.
It looks like you're expecting the JSON Pointer to resolve the { $ref: "entity" }
at main#/entity
, but JSON Pointers don't resolve references.
The code you posted may just be an example to illustrate your point, but given that entity#/properties/id
is just
{ "type": "string" }
it may just make more sense to repeat that in your request
object rather than trying to reference into entity
to get it. Typically references don't extract subschemas that way. They can, but it's not advised to do so.
If you'd really like to reference it, I suggest you extract that out into a new schema and reference it from both places.
Another option is to compose all of these into a single schema and make use of $defs
to house any reusable pieces.
英文:
Your main
schema is precisely this:
{
entity: { $ref: "entity" },
request: { $ref: "request" }
}
The JSON Pointer #/entity/properties/id
doesn't resolve to a location within main
.
It looks like you're expecting the JSON Pointer to resolve the { $ref: "entity" }
at main#/entity
, but JSON Pointers don't resolve references.
The code you posted may just be an example to illustrate your point, but given that entity#/properties/id
is just
{ "type": "string" }
it may just make more sense to repeat that in your request
object rather than trying to reference into entity
to get it. Typically references don't extract subschemas that way. They can, but it's not advised to do so.
If you'd really like to reference it, I suggest you extract that out into a new schema and reference it from both places.
Another option is to compose all of these into a single schema and make use of $defs
to house any reusable pieces.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论