通过相对文件路径解析 $ref
Resolve $ref by relative file path
我想将 json-schemas 拆分成多个本地文件,并尽可能简单直接地引用它们。为此,我的第一直觉是 $ref
相对于当前文件的路径。
然而,json-schema 方式似乎没有标准案例,因为 $ref
是相对于 $id
解析的,并且“当前文件的路径" 不可用。 $id
可悲的是mixes two purposes(为什么要这样做?):
- 唯一标识符
$ref
的基本 URI
我想到了这个解决方法,通过将本地路径拖动到 $id
中,但这显然破坏了 $id
的另一个目的:
import Ajv from 'ajv';
import * as fs from 'fs/promises';
const load = async (uri: string) => {
const schema = JSON.parse(await fs.readFile(uri, 'utf8'));
schema.$id = uri; // do the deed
return schema;
};
const ajv = new Ajv({ loadSchema: load });
(async () => {
const startSchema = await load('some/path/example.json');
const validate = await ajv.compileAsync(startSchema);
})();
幸运的是,就我而言,我真的不关心 $id
否则,但是没有标准的方法吗?我无法想象这是一个异常的用例。
示例结构,因为它被要求:
本地文件夹结构示例:
schemas
├─ sub
│ └─ start.schema.json
└─ referenced.schema.json
start.schema.json:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/schemas/id1",
"type": "object",
"properties": {
"bad": { "$ref": "../referenced.schema.json" }
}
}
referenced.schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/schemas/id2",
"type": "integer"
}
解析将相对于$id
,如果我不替换它:https://example.com/referenced.schema.json
,这是完全错误的。
选项 1:对所有 $id
使用 file://
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "file:///path/to/schemas/id1",
"type": "object",
"properties": {
"bad": { "$ref": "../referenced.schema.json" }
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "file:///path/to/schemas/id2",
"type": "integer"
}
选项 2:预加载所有架构
import Ajv from 'ajv';
import * as fs from 'fs/promises';
const load = async (uri: string) => {
return JSON.parse(await fs.readFile(uri, 'utf8'));
};
const ajv = new Ajv();
(async () => {
ajv.addSchema(await load('schemas/sub/start.schema.json'));
ajv.addSchema(await load('schemas/referenced.schema.json'));
const validate = ajv.getSchema("https://example.com/schemas/id1");
})();
我想将 json-schemas 拆分成多个本地文件,并尽可能简单直接地引用它们。为此,我的第一直觉是 $ref
相对于当前文件的路径。
然而,json-schema 方式似乎没有标准案例,因为 $ref
是相对于 $id
解析的,并且“当前文件的路径" 不可用。 $id
可悲的是mixes two purposes(为什么要这样做?):
- 唯一标识符
$ref
的基本 URI
我想到了这个解决方法,通过将本地路径拖动到 $id
中,但这显然破坏了 $id
的另一个目的:
import Ajv from 'ajv';
import * as fs from 'fs/promises';
const load = async (uri: string) => {
const schema = JSON.parse(await fs.readFile(uri, 'utf8'));
schema.$id = uri; // do the deed
return schema;
};
const ajv = new Ajv({ loadSchema: load });
(async () => {
const startSchema = await load('some/path/example.json');
const validate = await ajv.compileAsync(startSchema);
})();
幸运的是,就我而言,我真的不关心 $id
否则,但是没有标准的方法吗?我无法想象这是一个异常的用例。
示例结构,因为它被要求:
本地文件夹结构示例:
schemas
├─ sub
│ └─ start.schema.json
└─ referenced.schema.json
start.schema.json:
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://example.com/schemas/id1", "type": "object", "properties": { "bad": { "$ref": "../referenced.schema.json" } } }
referenced.schema.json
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://example.com/schemas/id2", "type": "integer" }
解析将相对于$id
,如果我不替换它:https://example.com/referenced.schema.json
,这是完全错误的。
选项 1:对所有 $id
file://
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "file:///path/to/schemas/id1",
"type": "object",
"properties": {
"bad": { "$ref": "../referenced.schema.json" }
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "file:///path/to/schemas/id2",
"type": "integer"
}
选项 2:预加载所有架构
import Ajv from 'ajv';
import * as fs from 'fs/promises';
const load = async (uri: string) => {
return JSON.parse(await fs.readFile(uri, 'utf8'));
};
const ajv = new Ajv();
(async () => {
ajv.addSchema(await load('schemas/sub/start.schema.json'));
ajv.addSchema(await load('schemas/referenced.schema.json'));
const validate = ajv.getSchema("https://example.com/schemas/id1");
})();