schema-dsl 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +130 -113
- package/LICENSE +21 -21
- package/README.md +628 -628
- package/dist/{DslBuilder-DkLaOo9Q.d.ts → DslBuilder-BIgQOAXp.d.ts} +2 -0
- package/dist/{DslBuilder-DQDN0ZxZ.d.cts → DslBuilder-CjHTucNQ.d.cts} +2 -0
- package/dist/{Validator-hFWKGxir.d.ts → Validator-CllRdrY0.d.ts} +1 -1
- package/dist/{Validator-C7GsVQOH.d.cts → Validator-D6okG9tr.d.cts} +1 -1
- package/dist/index.cjs +75 -29
- package/dist/index.d.cts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +75 -29
- package/dist/plugins/custom-format.cjs +33 -17
- package/dist/plugins/custom-format.d.cts +1 -1
- package/dist/plugins/custom-format.d.ts +1 -1
- package/dist/plugins/custom-format.js +33 -17
- package/dist/plugins/custom-type-example.cjs +33 -17
- package/dist/plugins/custom-type-example.d.cts +1 -1
- package/dist/plugins/custom-type-example.d.ts +1 -1
- package/dist/plugins/custom-type-example.js +33 -17
- package/dist/plugins/custom-validator.cjs +0 -2
- package/dist/plugins/custom-validator.d.cts +1 -1
- package/dist/plugins/custom-validator.d.ts +1 -1
- package/dist/plugins/custom-validator.js +0 -2
- package/docs/FEATURE-INDEX.md +553 -553
- package/docs/add-custom-locale.md +496 -496
- package/docs/add-keyword.md +24 -24
- package/docs/api-reference.md +1047 -1047
- package/docs/api.md +13 -13
- package/docs/best-practices-project-structure.md +417 -417
- package/docs/best-practices.md +712 -712
- package/docs/cache-manager.md +344 -344
- package/docs/compile.md +45 -45
- package/docs/conditional-api.md +1307 -1307
- package/docs/custom-extensions-guide.md +339 -339
- package/docs/design-philosophy.md +606 -606
- package/docs/doc-index.md +324 -324
- package/docs/dsl-syntax.md +714 -714
- package/docs/dynamic-locale.md +608 -608
- package/docs/enum.md +482 -482
- package/docs/error-handling.md +1975 -1975
- package/docs/export-guide.md +501 -501
- package/docs/export-limitations.md +567 -567
- package/docs/faq.md +596 -596
- package/docs/frontend-i18n-guide.md +307 -307
- package/docs/i18n-user-guide.md +487 -487
- package/docs/i18n.md +476 -476
- package/docs/index.md +48 -48
- package/docs/json-schema-basics.md +40 -40
- package/docs/label-vs-description.md +271 -271
- package/docs/markdown-exporter.md +406 -406
- package/docs/mongodb-exporter.md +302 -302
- package/docs/multi-language.md +26 -26
- package/docs/multi-type-support.md +322 -322
- package/docs/mysql-exporter.md +280 -280
- package/docs/number-operators.md +449 -449
- package/docs/optional-marker-guide.md +326 -326
- package/docs/performance-guide.md +49 -49
- package/docs/plugin-system.md +381 -381
- package/docs/plugin-type-registration.md +34 -34
- package/docs/postgresql-exporter.md +311 -311
- package/docs/public/favicon.svg +4 -4
- package/docs/quick-start.md +435 -435
- package/docs/runtime-locale-support.md +532 -532
- package/docs/schema-helper.md +345 -345
- package/docs/schema-utils-advanced-issues.md +23 -23
- package/docs/schema-utils-best-practices.md +20 -20
- package/docs/schema-utils-chaining.md +150 -150
- package/docs/schema-utils.md +524 -524
- package/docs/security-checklist.md +20 -20
- package/docs/string-extensions.md +488 -488
- package/docs/troubleshooting.md +486 -486
- package/docs/type-converter.md +310 -310
- package/docs/type-reference.md +242 -242
- package/docs/typescript-guide.md +584 -584
- package/docs/union-type-guide.md +157 -157
- package/docs/union-types.md +284 -284
- package/docs/validate-async.md +491 -491
- package/docs/validate-batch.md +49 -49
- package/docs/validate-dsl-object-support.md +578 -578
- package/docs/validate.md +506 -506
- package/docs/validation-guide.md +502 -502
- package/docs/validator.md +39 -39
- package/package.json +131 -131
- package/plugins/custom-format.cjs +8 -8
- package/plugins/custom-type-example.cjs +8 -8
- package/plugins/custom-validator.cjs +8 -8
- package/src/adapters/DslAdapter.ts +111 -111
- package/src/adapters/index.ts +1 -1
- package/src/config/constants.ts +83 -83
- package/src/config/index.ts +2 -2
- package/src/config/patterns.ts +77 -77
- package/src/core/CacheManager.ts +169 -159
- package/src/core/ConditionalBuilder.ts +382 -382
- package/src/core/ConditionalRuntime.ts +27 -27
- package/src/core/ConditionalValidator.ts +254 -254
- package/src/core/DslBuilder.ts +687 -677
- package/src/core/ErrorCodes.ts +38 -38
- package/src/core/ErrorFormatter.ts +271 -271
- package/src/core/JSONSchemaCore.ts +65 -65
- package/src/core/Locale.ts +187 -187
- package/src/core/MessageTemplate.ts +42 -42
- package/src/core/ObjectDslBuilder.ts +64 -64
- package/src/core/PluginManager.ts +326 -326
- package/src/core/StringExtensions.ts +140 -140
- package/src/core/TemplateEngine.ts +44 -44
- package/src/core/Validator.ts +448 -448
- package/src/errors/I18nError.ts +159 -159
- package/src/errors/ValidationError.ts +105 -105
- package/src/exporters/BaseExporter.ts +60 -60
- package/src/exporters/MarkdownExporter.ts +305 -305
- package/src/exporters/MongoDBExporter.ts +126 -126
- package/src/exporters/MySQLExporter.ts +156 -155
- package/src/exporters/PostgreSQLExporter.ts +222 -222
- package/src/exporters/index.ts +18 -18
- package/src/index.ts +651 -633
- package/src/locales/en-US.ts +160 -160
- package/src/locales/es-ES.ts +160 -160
- package/src/locales/fr-FR.ts +160 -160
- package/src/locales/index.ts +103 -103
- package/src/locales/ja-JP.ts +160 -160
- package/src/locales/types.ts +156 -156
- package/src/locales/zh-CN.ts +160 -160
- package/src/parser/ConstraintParser.ts +101 -101
- package/src/parser/DslParser.ts +470 -470
- package/src/parser/SchemaCompiler.ts +66 -66
- package/src/parser/TypeRegistry.ts +250 -250
- package/src/parser/index.ts +6 -6
- package/src/plugins/custom-format.ts +124 -126
- package/src/plugins/custom-type-example.ts +106 -108
- package/src/plugins/custom-validator.ts +138 -140
- package/src/types/conditional.ts +28 -28
- package/src/types/config.ts +59 -59
- package/src/types/dsl.ts +131 -131
- package/src/types/error.ts +60 -60
- package/src/types/index.ts +17 -17
- package/src/types/infer.ts +127 -127
- package/src/types/plugin.ts +58 -58
- package/src/types/safe-regex.d.ts +9 -9
- package/src/types/schema.ts +66 -66
- package/src/types/validate.ts +71 -71
- package/src/utils/SchemaHelper.ts +196 -196
- package/src/utils/SchemaUtils.ts +365 -346
- package/src/utils/TypeConverter.ts +215 -215
- package/src/utils/index.ts +10 -10
- package/src/validators/CustomKeywords.ts +477 -477
package/docs/validate.md
CHANGED
|
@@ -1,506 +1,506 @@
|
|
|
1
|
-
# validate 方法详细文档
|
|
2
|
-
|
|
3
|
-
## 📑 目录
|
|
4
|
-
|
|
5
|
-
### 基础概念
|
|
6
|
-
- [概述](#概述) - validate 方法介绍
|
|
7
|
-
- [方法签名](#方法签名) - API 定义
|
|
8
|
-
|
|
9
|
-
### 参数详解
|
|
10
|
-
- [参数详解](#参数详解)
|
|
11
|
-
- [schema 参数](#schema-参数)
|
|
12
|
-
- [options 对象属性](#options-对象属性)
|
|
13
|
-
- [返回值详解](#返回值详解)
|
|
14
|
-
- [valid (Boolean)](#valid-boolean)
|
|
15
|
-
- [errors (Array)](#errors-array)
|
|
16
|
-
- [data (Any)](#data-any)
|
|
17
|
-
|
|
18
|
-
### 使用示例
|
|
19
|
-
- [基础示例](#基础示例)
|
|
20
|
-
- [示例 1: 验证简单对象](#示例-1-验证简单对象)
|
|
21
|
-
- [示例 2: 验证复杂对象](#示例-2-验证复杂对象)
|
|
22
|
-
- [示例 3: 处理验证错误](#示例-3-处理验证错误)
|
|
23
|
-
- [示例 4: 使用默认值](#示例-4-使用默认值)
|
|
24
|
-
|
|
25
|
-
### 高级功能
|
|
26
|
-
- [高级用法](#高级用法)
|
|
27
|
-
- [批量验证](#批量验证)
|
|
28
|
-
- [自定义错误格式](#自定义错误格式)
|
|
29
|
-
- [性能优化](#性能优化)
|
|
30
|
-
|
|
31
|
-
### 参考资料
|
|
32
|
-
- [相关文档](#相关文档)
|
|
33
|
-
- [API 参考](#api-参考)
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## 概述
|
|
38
|
-
|
|
39
|
-
`validate` 是 Validator 类的核心方法,用于验证数据是否符合 JSON Schema 定义。基于高性能的 ajv 验证器实现。
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## 方法签名
|
|
44
|
-
|
|
45
|
-
```javascript
|
|
46
|
-
validator.validate(schema, data, options = {})
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**参数说明**:
|
|
50
|
-
- `schema` (Object|Function): JSON Schema 对象或已编译的验证函数
|
|
51
|
-
- `data` (Any): 待验证的数据
|
|
52
|
-
- `options` (Object): 验证选项(可选)
|
|
53
|
-
|
|
54
|
-
**返回值**:
|
|
55
|
-
```javascript
|
|
56
|
-
{
|
|
57
|
-
valid: Boolean, // 是否有效
|
|
58
|
-
errors: Array, // 成功时为空数组,失败时为错误列表
|
|
59
|
-
data: Any // 当前实现会返回本次验证数据(可能被 useDefaults 修改)
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
当前实现中,`data` 与 `errors` 都会随结果一并返回:成功时 `errors` 为空数组,验证失败时仍会保留 `data` 以便排查输入。
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## 参数详解
|
|
68
|
-
|
|
69
|
-
### schema 参数
|
|
70
|
-
|
|
71
|
-
JSON Schema 对象,支持 JSON Schema Draft 7 标准。
|
|
72
|
-
|
|
73
|
-
| 参数类型 | 说明 | 来源 |
|
|
74
|
-
|---------|------|------|
|
|
75
|
-
| Object | JSON Schema 对象 | JSON Schema 标准 ✅ |
|
|
76
|
-
| Function | 已编译的验证函数(通过 `compile()` 生成) | ajv ✅ |
|
|
77
|
-
|
|
78
|
-
### options 对象属性
|
|
79
|
-
|
|
80
|
-
`validator.validate(schema, data, options)` 当前按本次调用实际读取以下参数:
|
|
81
|
-
|
|
82
|
-
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
83
|
-
|------|------|------|--------|------|
|
|
84
|
-
| `format` | Boolean | 否 | `true` | 是否格式化错误信息 |
|
|
85
|
-
| `locale` | String | 否 | — | 动态指定语言,如 `'zh-CN'`、`'en-US'`、`'ja-JP'` |
|
|
86
|
-
| `messages` | Object | 否 | — | 自定义错误消息覆盖 |
|
|
87
|
-
|
|
88
|
-
### 相关配置入口
|
|
89
|
-
|
|
90
|
-
以下能力**不属于** `validator.validate(schema, data, options)` 的逐次调用参数:
|
|
91
|
-
|
|
92
|
-
| 能力 | 正确入口 | 说明 |
|
|
93
|
-
|------|----------|------|
|
|
94
|
-
| `allErrors` / `useDefaults` / `coerceTypes` / `removeAdditional` / `cache` | `new Validator(options)` | 这些配置在创建 `Validator` 实例时注入到底层 AJV / 缓存层 |
|
|
95
|
-
| `strict` | Schema 本身 | 如果需要禁止额外字段,请在 schema 层使用 `DslBuilder.strict()` 或等价的 schema 级约束 |
|
|
96
|
-
| `coerce` | 顶层 `validate()` / `validateAsync()` 便捷函数 | 顶层 helper 默认会做字符串 → 数字 / 布尔值的便捷转换,传 `{ coerce: false }` 可关闭 |
|
|
97
|
-
|
|
98
|
-
如果你需要在**单次调用**中覆盖错误输出,请使用上表中的 `format`、`locale`、`messages`;如果你需要调整验证器行为,请优先在 `Validator` 构造阶段配置。
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## 返回值详解
|
|
103
|
-
|
|
104
|
-
### valid (Boolean)
|
|
105
|
-
|
|
106
|
-
表示数据是否通过验证。
|
|
107
|
-
|
|
108
|
-
```javascript
|
|
109
|
-
result.valid === true // 验证通过
|
|
110
|
-
result.valid === false // 验证失败
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### errors (Array)
|
|
114
|
-
|
|
115
|
-
验证错误列表。当前实现成功时返回空数组,验证失败时包含详细错误信息。
|
|
116
|
-
|
|
117
|
-
**错误对象结构**:
|
|
118
|
-
```javascript
|
|
119
|
-
{
|
|
120
|
-
path: String, // 错误字段路径,如 'user.email'
|
|
121
|
-
message: String, // 错误描述信息
|
|
122
|
-
keyword: String, // 触发的 Schema 关键字
|
|
123
|
-
params: Object // 错误相关参数
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### data (Any)
|
|
128
|
-
|
|
129
|
-
验证后的数据。当前实现即使在验证失败时也会保留本次验证数据,便于排查输入;如果 Validator 配置了 `useDefaults: true`,则也可能反映 Schema 中应用后的默认值。
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## 基础示例
|
|
134
|
-
|
|
135
|
-
### 示例 1: 验证简单对象
|
|
136
|
-
|
|
137
|
-
```javascript
|
|
138
|
-
const { Validator } = require('schema-dsl');
|
|
139
|
-
|
|
140
|
-
const validator = new Validator();
|
|
141
|
-
|
|
142
|
-
const schema = {
|
|
143
|
-
type: 'object',
|
|
144
|
-
properties: {
|
|
145
|
-
name: { type: 'string' },
|
|
146
|
-
age: { type: 'number' }
|
|
147
|
-
},
|
|
148
|
-
required: ['name']
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const result = validator.validate(schema, {
|
|
152
|
-
name: 'John',
|
|
153
|
-
age: 25
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
console.log(result.valid); // true
|
|
157
|
-
console.log(result.errors); // []
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### 示例 2: 处理验证失败
|
|
161
|
-
|
|
162
|
-
```javascript
|
|
163
|
-
const result = validator.validate(schema, {
|
|
164
|
-
age: 'invalid'
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
console.log(result.valid); // false
|
|
168
|
-
console.log(result.errors);
|
|
169
|
-
// 当前实现返回格式化后的错误列表:
|
|
170
|
-
// [
|
|
171
|
-
// { path: 'name', message: 'name不能为空' },
|
|
172
|
-
// { path: 'age', message: 'age应该是 number 类型' }
|
|
173
|
-
// ]
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## 高级示例
|
|
179
|
-
|
|
180
|
-
### 示例 3: 验证字符串约束
|
|
181
|
-
|
|
182
|
-
```javascript
|
|
183
|
-
const schema = {
|
|
184
|
-
type: 'string',
|
|
185
|
-
minLength: 3,
|
|
186
|
-
maxLength: 32,
|
|
187
|
-
pattern: '^[a-zA-Z0-9]+$'
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// 有效数据
|
|
191
|
-
console.log(validator.validate(schema, 'john123').valid); // true
|
|
192
|
-
|
|
193
|
-
// 太短
|
|
194
|
-
console.log(validator.validate(schema, 'ab').valid); // false
|
|
195
|
-
|
|
196
|
-
// 包含非法字符
|
|
197
|
-
console.log(validator.validate(schema, 'john-123').valid); // false
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### 示例 4: 验证数字范围
|
|
201
|
-
|
|
202
|
-
```javascript
|
|
203
|
-
const schema = {
|
|
204
|
-
type: 'number',
|
|
205
|
-
minimum: 0,
|
|
206
|
-
maximum: 100
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
console.log(validator.validate(schema, 50).valid); // true
|
|
210
|
-
console.log(validator.validate(schema, -1).valid); // false
|
|
211
|
-
console.log(validator.validate(schema, 101).valid); // false
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### 示例 5: 验证邮箱格式
|
|
215
|
-
|
|
216
|
-
```javascript
|
|
217
|
-
const schema = {
|
|
218
|
-
type: 'string',
|
|
219
|
-
format: 'email'
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
console.log(validator.validate(schema, 'test@example.com').valid); // true
|
|
223
|
-
console.log(validator.validate(schema, 'invalid-email').valid); // false
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### 示例 6: 验证枚举值
|
|
227
|
-
|
|
228
|
-
```javascript
|
|
229
|
-
const schema = {
|
|
230
|
-
type: 'string',
|
|
231
|
-
enum: ['active', 'inactive', 'pending']
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
console.log(validator.validate(schema, 'active').valid); // true
|
|
235
|
-
console.log(validator.validate(schema, 'invalid').valid); // false
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### 示例 7: 验证嵌套对象
|
|
239
|
-
|
|
240
|
-
```javascript
|
|
241
|
-
const schema = {
|
|
242
|
-
type: 'object',
|
|
243
|
-
properties: {
|
|
244
|
-
user: {
|
|
245
|
-
type: 'object',
|
|
246
|
-
properties: {
|
|
247
|
-
name: { type: 'string' },
|
|
248
|
-
email: { type: 'string', format: 'email' }
|
|
249
|
-
},
|
|
250
|
-
required: ['name', 'email']
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
const data = {
|
|
256
|
-
user: {
|
|
257
|
-
name: 'John',
|
|
258
|
-
email: 'john@example.com'
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
const result = validator.validate(schema, data);
|
|
263
|
-
console.log(result.valid); // true
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### 示例 8: 验证数组
|
|
267
|
-
|
|
268
|
-
```javascript
|
|
269
|
-
const schema = {
|
|
270
|
-
type: 'array',
|
|
271
|
-
items: { type: 'string' },
|
|
272
|
-
minItems: 1,
|
|
273
|
-
maxItems: 10
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
console.log(validator.validate(schema, ['a', 'b', 'c']).valid); // true
|
|
277
|
-
console.log(validator.validate(schema, []).valid); // false (minItems)
|
|
278
|
-
console.log(validator.validate(schema, [1, 2, 3]).valid); // false (type)
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
## 使用默认值
|
|
284
|
-
|
|
285
|
-
当 Validator 配置了 `useDefaults: true` 时,会自动应用 Schema 中的默认值。
|
|
286
|
-
|
|
287
|
-
```javascript
|
|
288
|
-
const validator = new Validator({ useDefaults: true });
|
|
289
|
-
|
|
290
|
-
const schema = {
|
|
291
|
-
type: 'object',
|
|
292
|
-
properties: {
|
|
293
|
-
name: { type: 'string' },
|
|
294
|
-
status: { type: 'string', default: 'active' }
|
|
295
|
-
}
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
const result = validator.validate(schema, { name: 'John' });
|
|
299
|
-
|
|
300
|
-
console.log(result.valid); // true
|
|
301
|
-
console.log(result.data); // { name: 'John', status: 'active' }
|
|
302
|
-
console.log(result.data.status); // 'active' (自动应用默认值)
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
## 使用已编译的验证函数
|
|
308
|
-
|
|
309
|
-
为了提高性能,可以先编译 Schema,然后重复使用编译后的验证函数。
|
|
310
|
-
|
|
311
|
-
```javascript
|
|
312
|
-
// 编译 Schema
|
|
313
|
-
const validateFn = validator.compile(schema);
|
|
314
|
-
|
|
315
|
-
// 重复使用(性能更好)
|
|
316
|
-
const result1 = validator.validate(validateFn, data1);
|
|
317
|
-
const result2 = validator.validate(validateFn, data2);
|
|
318
|
-
const result3 = validator.validate(validateFn, data3);
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## 错误处理最佳实践
|
|
324
|
-
|
|
325
|
-
### 实践 1: 展示用户友好的错误信息
|
|
326
|
-
|
|
327
|
-
```javascript
|
|
328
|
-
const result = validator.validate(schema, data);
|
|
329
|
-
|
|
330
|
-
if (!result.valid) {
|
|
331
|
-
// 格式化错误信息
|
|
332
|
-
result.errors.forEach(err => {
|
|
333
|
-
console.log(`字段 "${err.path}": ${err.message}`);
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
// 或者整体提示
|
|
337
|
-
console.log(`验证失败,共 ${result.errors.length} 个错误`);
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### 实践 2: API 响应中返回错误
|
|
342
|
-
|
|
343
|
-
```javascript
|
|
344
|
-
const result = validator.validate(schema, req.body);
|
|
345
|
-
|
|
346
|
-
if (!result.valid) {
|
|
347
|
-
return res.status(400).json({
|
|
348
|
-
success: false,
|
|
349
|
-
message: '数据验证失败',
|
|
350
|
-
errors: result.errors.map(err => ({
|
|
351
|
-
field: err.path,
|
|
352
|
-
message: err.message
|
|
353
|
-
}))
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// 验证通过,继续处理
|
|
358
|
-
processData(result.data);
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### 实践 3: 抛出异常
|
|
362
|
-
|
|
363
|
-
```javascript
|
|
364
|
-
const result = validator.validate(schema, data);
|
|
365
|
-
|
|
366
|
-
if (!result.valid) {
|
|
367
|
-
const error = new ValidationError(result.errors, data);
|
|
368
|
-
throw error;
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
---
|
|
373
|
-
|
|
374
|
-
## 性能优化建议
|
|
375
|
-
|
|
376
|
-
### 建议 1: 复用 Validator 实例
|
|
377
|
-
|
|
378
|
-
```javascript
|
|
379
|
-
// ✅ 好:复用实例
|
|
380
|
-
const validator = new Validator();
|
|
381
|
-
|
|
382
|
-
app.post('/api/users', (req, res) => {
|
|
383
|
-
const result = validator.validate(userSchema, req.body);
|
|
384
|
-
// ...
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// ❌ 不好:每次创建新实例
|
|
388
|
-
app.post('/api/users', (req, res) => {
|
|
389
|
-
const validator = new Validator(); // 不推荐
|
|
390
|
-
const result = validator.validate(userSchema, req.body);
|
|
391
|
-
// ...
|
|
392
|
-
});
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### 建议 2: 预编译 Schema
|
|
396
|
-
|
|
397
|
-
```javascript
|
|
398
|
-
// 应用启动时预编译
|
|
399
|
-
const validateUser = validator.compile(userSchema);
|
|
400
|
-
const validateProduct = validator.compile(productSchema);
|
|
401
|
-
|
|
402
|
-
// 使用时直接验证(更快)
|
|
403
|
-
app.post('/api/users', (req, res) => {
|
|
404
|
-
const result = validator.validate(validateUser, req.body);
|
|
405
|
-
// ...
|
|
406
|
-
});
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### 建议 3: 使用缓存
|
|
410
|
-
|
|
411
|
-
```javascript
|
|
412
|
-
// 显式编译并复用缓存键
|
|
413
|
-
const validateUser = validator.compile(schema, 'user-schema');
|
|
414
|
-
|
|
415
|
-
console.log(validateUser(data));
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
---
|
|
419
|
-
|
|
420
|
-
## 常见问题
|
|
421
|
-
|
|
422
|
-
---
|
|
423
|
-
|
|
424
|
-
## 对应示例文件
|
|
425
|
-
|
|
426
|
-
**示例入口**: [validate.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/validate.ts)
|
|
427
|
-
**说明**: 覆盖顶层 `validate()` 的成功/失败路径、默认类型转换,以及关闭 `coerce` 后的行为差异。
|
|
428
|
-
|
|
429
|
-
### Q1: 如何验证可选字段?
|
|
430
|
-
|
|
431
|
-
不在 `required` 数组中的字段自动为可选:
|
|
432
|
-
|
|
433
|
-
```javascript
|
|
434
|
-
const schema = {
|
|
435
|
-
type: 'object',
|
|
436
|
-
properties: {
|
|
437
|
-
name: { type: 'string' },
|
|
438
|
-
age: { type: 'number' } // age 是可选的
|
|
439
|
-
},
|
|
440
|
-
required: ['name'] // 只有 name 是必填的
|
|
441
|
-
};
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
### Q2: 如何允许额外字段?
|
|
445
|
-
|
|
446
|
-
JSON Schema 默认允许额外字段。如果要禁止额外字段:
|
|
447
|
-
|
|
448
|
-
```javascript
|
|
449
|
-
const schema = {
|
|
450
|
-
type: 'object',
|
|
451
|
-
properties: {
|
|
452
|
-
name: { type: 'string' }
|
|
453
|
-
},
|
|
454
|
-
additionalProperties: false // 禁止额外字段
|
|
455
|
-
};
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
### Q3: 如何验证多种类型?
|
|
459
|
-
|
|
460
|
-
使用 `anyOf` 或 `oneOf`:
|
|
461
|
-
|
|
462
|
-
```javascript
|
|
463
|
-
const schema = {
|
|
464
|
-
type: 'object',
|
|
465
|
-
properties: {
|
|
466
|
-
value: {
|
|
467
|
-
anyOf: [
|
|
468
|
-
{ type: 'string' },
|
|
469
|
-
{ type: 'number' }
|
|
470
|
-
]
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
### Q4: 性能如何?
|
|
477
|
-
|
|
478
|
-
基于 ajv,业界最快的 JSON Schema 验证器:
|
|
479
|
-
- 验证速度 >15,000 ops/s
|
|
480
|
-
- 内置编译缓存
|
|
481
|
-
- 支持批量验证优化
|
|
482
|
-
|
|
483
|
-
---
|
|
484
|
-
|
|
485
|
-
## 相关文档
|
|
486
|
-
|
|
487
|
-
- [Validator 类概述](./validator.md)
|
|
488
|
-
- [compile 方法](./compile.md) - 编译 Schema 提升性能
|
|
489
|
-
- [validateBatch 方法](./validate-batch.md) - 批量验证
|
|
490
|
-
- [addKeyword 方法](./add-keyword.md) - 添加自定义验证
|
|
491
|
-
- [JSON Schema 基础](./json-schema-basics.md)
|
|
492
|
-
|
|
493
|
-
---
|
|
494
|
-
|
|
495
|
-
## 外部参考
|
|
496
|
-
|
|
497
|
-
- [JSON Schema 官方文档](https://json-schema.org/)
|
|
498
|
-
- [ajv 文档](https://ajv.js.org/)
|
|
499
|
-
- [JSON Schema Validator](https://www.jsonschemavalidator.net/) - 在线测试工具
|
|
500
|
-
|
|
501
|
-
---
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
**最后更新**: 2025-12-24
|
|
505
|
-
|
|
506
|
-
|
|
1
|
+
# validate 方法详细文档
|
|
2
|
+
|
|
3
|
+
## 📑 目录
|
|
4
|
+
|
|
5
|
+
### 基础概念
|
|
6
|
+
- [概述](#概述) - validate 方法介绍
|
|
7
|
+
- [方法签名](#方法签名) - API 定义
|
|
8
|
+
|
|
9
|
+
### 参数详解
|
|
10
|
+
- [参数详解](#参数详解)
|
|
11
|
+
- [schema 参数](#schema-参数)
|
|
12
|
+
- [options 对象属性](#options-对象属性)
|
|
13
|
+
- [返回值详解](#返回值详解)
|
|
14
|
+
- [valid (Boolean)](#valid-boolean)
|
|
15
|
+
- [errors (Array)](#errors-array)
|
|
16
|
+
- [data (Any)](#data-any)
|
|
17
|
+
|
|
18
|
+
### 使用示例
|
|
19
|
+
- [基础示例](#基础示例)
|
|
20
|
+
- [示例 1: 验证简单对象](#示例-1-验证简单对象)
|
|
21
|
+
- [示例 2: 验证复杂对象](#示例-2-验证复杂对象)
|
|
22
|
+
- [示例 3: 处理验证错误](#示例-3-处理验证错误)
|
|
23
|
+
- [示例 4: 使用默认值](#示例-4-使用默认值)
|
|
24
|
+
|
|
25
|
+
### 高级功能
|
|
26
|
+
- [高级用法](#高级用法)
|
|
27
|
+
- [批量验证](#批量验证)
|
|
28
|
+
- [自定义错误格式](#自定义错误格式)
|
|
29
|
+
- [性能优化](#性能优化)
|
|
30
|
+
|
|
31
|
+
### 参考资料
|
|
32
|
+
- [相关文档](#相关文档)
|
|
33
|
+
- [API 参考](#api-参考)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 概述
|
|
38
|
+
|
|
39
|
+
`validate` 是 Validator 类的核心方法,用于验证数据是否符合 JSON Schema 定义。基于高性能的 ajv 验证器实现。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 方法签名
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
validator.validate(schema, data, options = {})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**参数说明**:
|
|
50
|
+
- `schema` (Object|Function): JSON Schema 对象或已编译的验证函数
|
|
51
|
+
- `data` (Any): 待验证的数据
|
|
52
|
+
- `options` (Object): 验证选项(可选)
|
|
53
|
+
|
|
54
|
+
**返回值**:
|
|
55
|
+
```javascript
|
|
56
|
+
{
|
|
57
|
+
valid: Boolean, // 是否有效
|
|
58
|
+
errors: Array, // 成功时为空数组,失败时为错误列表
|
|
59
|
+
data: Any // 当前实现会返回本次验证数据(可能被 useDefaults 修改)
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
当前实现中,`data` 与 `errors` 都会随结果一并返回:成功时 `errors` 为空数组,验证失败时仍会保留 `data` 以便排查输入。
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 参数详解
|
|
68
|
+
|
|
69
|
+
### schema 参数
|
|
70
|
+
|
|
71
|
+
JSON Schema 对象,支持 JSON Schema Draft 7 标准。
|
|
72
|
+
|
|
73
|
+
| 参数类型 | 说明 | 来源 |
|
|
74
|
+
|---------|------|------|
|
|
75
|
+
| Object | JSON Schema 对象 | JSON Schema 标准 ✅ |
|
|
76
|
+
| Function | 已编译的验证函数(通过 `compile()` 生成) | ajv ✅ |
|
|
77
|
+
|
|
78
|
+
### options 对象属性
|
|
79
|
+
|
|
80
|
+
`validator.validate(schema, data, options)` 当前按本次调用实际读取以下参数:
|
|
81
|
+
|
|
82
|
+
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
83
|
+
|------|------|------|--------|------|
|
|
84
|
+
| `format` | Boolean | 否 | `true` | 是否格式化错误信息 |
|
|
85
|
+
| `locale` | String | 否 | — | 动态指定语言,如 `'zh-CN'`、`'en-US'`、`'ja-JP'` |
|
|
86
|
+
| `messages` | Object | 否 | — | 自定义错误消息覆盖 |
|
|
87
|
+
|
|
88
|
+
### 相关配置入口
|
|
89
|
+
|
|
90
|
+
以下能力**不属于** `validator.validate(schema, data, options)` 的逐次调用参数:
|
|
91
|
+
|
|
92
|
+
| 能力 | 正确入口 | 说明 |
|
|
93
|
+
|------|----------|------|
|
|
94
|
+
| `allErrors` / `useDefaults` / `coerceTypes` / `removeAdditional` / `cache` | `new Validator(options)` | 这些配置在创建 `Validator` 实例时注入到底层 AJV / 缓存层 |
|
|
95
|
+
| `strict` | Schema 本身 | 如果需要禁止额外字段,请在 schema 层使用 `DslBuilder.strict()` 或等价的 schema 级约束 |
|
|
96
|
+
| `coerce` | 顶层 `validate()` / `validateAsync()` 便捷函数 | 顶层 helper 默认会做字符串 → 数字 / 布尔值的便捷转换,传 `{ coerce: false }` 可关闭 |
|
|
97
|
+
|
|
98
|
+
如果你需要在**单次调用**中覆盖错误输出,请使用上表中的 `format`、`locale`、`messages`;如果你需要调整验证器行为,请优先在 `Validator` 构造阶段配置。
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 返回值详解
|
|
103
|
+
|
|
104
|
+
### valid (Boolean)
|
|
105
|
+
|
|
106
|
+
表示数据是否通过验证。
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
result.valid === true // 验证通过
|
|
110
|
+
result.valid === false // 验证失败
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### errors (Array)
|
|
114
|
+
|
|
115
|
+
验证错误列表。当前实现成功时返回空数组,验证失败时包含详细错误信息。
|
|
116
|
+
|
|
117
|
+
**错误对象结构**:
|
|
118
|
+
```javascript
|
|
119
|
+
{
|
|
120
|
+
path: String, // 错误字段路径,如 'user.email'
|
|
121
|
+
message: String, // 错误描述信息
|
|
122
|
+
keyword: String, // 触发的 Schema 关键字
|
|
123
|
+
params: Object // 错误相关参数
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### data (Any)
|
|
128
|
+
|
|
129
|
+
验证后的数据。当前实现即使在验证失败时也会保留本次验证数据,便于排查输入;如果 Validator 配置了 `useDefaults: true`,则也可能反映 Schema 中应用后的默认值。
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 基础示例
|
|
134
|
+
|
|
135
|
+
### 示例 1: 验证简单对象
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
const { Validator } = require('schema-dsl');
|
|
139
|
+
|
|
140
|
+
const validator = new Validator();
|
|
141
|
+
|
|
142
|
+
const schema = {
|
|
143
|
+
type: 'object',
|
|
144
|
+
properties: {
|
|
145
|
+
name: { type: 'string' },
|
|
146
|
+
age: { type: 'number' }
|
|
147
|
+
},
|
|
148
|
+
required: ['name']
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const result = validator.validate(schema, {
|
|
152
|
+
name: 'John',
|
|
153
|
+
age: 25
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
console.log(result.valid); // true
|
|
157
|
+
console.log(result.errors); // []
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 示例 2: 处理验证失败
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
const result = validator.validate(schema, {
|
|
164
|
+
age: 'invalid'
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
console.log(result.valid); // false
|
|
168
|
+
console.log(result.errors);
|
|
169
|
+
// 当前实现返回格式化后的错误列表:
|
|
170
|
+
// [
|
|
171
|
+
// { path: 'name', message: 'name不能为空' },
|
|
172
|
+
// { path: 'age', message: 'age应该是 number 类型' }
|
|
173
|
+
// ]
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 高级示例
|
|
179
|
+
|
|
180
|
+
### 示例 3: 验证字符串约束
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
const schema = {
|
|
184
|
+
type: 'string',
|
|
185
|
+
minLength: 3,
|
|
186
|
+
maxLength: 32,
|
|
187
|
+
pattern: '^[a-zA-Z0-9]+$'
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// 有效数据
|
|
191
|
+
console.log(validator.validate(schema, 'john123').valid); // true
|
|
192
|
+
|
|
193
|
+
// 太短
|
|
194
|
+
console.log(validator.validate(schema, 'ab').valid); // false
|
|
195
|
+
|
|
196
|
+
// 包含非法字符
|
|
197
|
+
console.log(validator.validate(schema, 'john-123').valid); // false
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 示例 4: 验证数字范围
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
const schema = {
|
|
204
|
+
type: 'number',
|
|
205
|
+
minimum: 0,
|
|
206
|
+
maximum: 100
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
console.log(validator.validate(schema, 50).valid); // true
|
|
210
|
+
console.log(validator.validate(schema, -1).valid); // false
|
|
211
|
+
console.log(validator.validate(schema, 101).valid); // false
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### 示例 5: 验证邮箱格式
|
|
215
|
+
|
|
216
|
+
```javascript
|
|
217
|
+
const schema = {
|
|
218
|
+
type: 'string',
|
|
219
|
+
format: 'email'
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
console.log(validator.validate(schema, 'test@example.com').valid); // true
|
|
223
|
+
console.log(validator.validate(schema, 'invalid-email').valid); // false
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 示例 6: 验证枚举值
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
const schema = {
|
|
230
|
+
type: 'string',
|
|
231
|
+
enum: ['active', 'inactive', 'pending']
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
console.log(validator.validate(schema, 'active').valid); // true
|
|
235
|
+
console.log(validator.validate(schema, 'invalid').valid); // false
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### 示例 7: 验证嵌套对象
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
const schema = {
|
|
242
|
+
type: 'object',
|
|
243
|
+
properties: {
|
|
244
|
+
user: {
|
|
245
|
+
type: 'object',
|
|
246
|
+
properties: {
|
|
247
|
+
name: { type: 'string' },
|
|
248
|
+
email: { type: 'string', format: 'email' }
|
|
249
|
+
},
|
|
250
|
+
required: ['name', 'email']
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const data = {
|
|
256
|
+
user: {
|
|
257
|
+
name: 'John',
|
|
258
|
+
email: 'john@example.com'
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const result = validator.validate(schema, data);
|
|
263
|
+
console.log(result.valid); // true
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 示例 8: 验证数组
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
const schema = {
|
|
270
|
+
type: 'array',
|
|
271
|
+
items: { type: 'string' },
|
|
272
|
+
minItems: 1,
|
|
273
|
+
maxItems: 10
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
console.log(validator.validate(schema, ['a', 'b', 'c']).valid); // true
|
|
277
|
+
console.log(validator.validate(schema, []).valid); // false (minItems)
|
|
278
|
+
console.log(validator.validate(schema, [1, 2, 3]).valid); // false (type)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 使用默认值
|
|
284
|
+
|
|
285
|
+
当 Validator 配置了 `useDefaults: true` 时,会自动应用 Schema 中的默认值。
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
const validator = new Validator({ useDefaults: true });
|
|
289
|
+
|
|
290
|
+
const schema = {
|
|
291
|
+
type: 'object',
|
|
292
|
+
properties: {
|
|
293
|
+
name: { type: 'string' },
|
|
294
|
+
status: { type: 'string', default: 'active' }
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const result = validator.validate(schema, { name: 'John' });
|
|
299
|
+
|
|
300
|
+
console.log(result.valid); // true
|
|
301
|
+
console.log(result.data); // { name: 'John', status: 'active' }
|
|
302
|
+
console.log(result.data.status); // 'active' (自动应用默认值)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## 使用已编译的验证函数
|
|
308
|
+
|
|
309
|
+
为了提高性能,可以先编译 Schema,然后重复使用编译后的验证函数。
|
|
310
|
+
|
|
311
|
+
```javascript
|
|
312
|
+
// 编译 Schema
|
|
313
|
+
const validateFn = validator.compile(schema);
|
|
314
|
+
|
|
315
|
+
// 重复使用(性能更好)
|
|
316
|
+
const result1 = validator.validate(validateFn, data1);
|
|
317
|
+
const result2 = validator.validate(validateFn, data2);
|
|
318
|
+
const result3 = validator.validate(validateFn, data3);
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 错误处理最佳实践
|
|
324
|
+
|
|
325
|
+
### 实践 1: 展示用户友好的错误信息
|
|
326
|
+
|
|
327
|
+
```javascript
|
|
328
|
+
const result = validator.validate(schema, data);
|
|
329
|
+
|
|
330
|
+
if (!result.valid) {
|
|
331
|
+
// 格式化错误信息
|
|
332
|
+
result.errors.forEach(err => {
|
|
333
|
+
console.log(`字段 "${err.path}": ${err.message}`);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// 或者整体提示
|
|
337
|
+
console.log(`验证失败,共 ${result.errors.length} 个错误`);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 实践 2: API 响应中返回错误
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
const result = validator.validate(schema, req.body);
|
|
345
|
+
|
|
346
|
+
if (!result.valid) {
|
|
347
|
+
return res.status(400).json({
|
|
348
|
+
success: false,
|
|
349
|
+
message: '数据验证失败',
|
|
350
|
+
errors: result.errors.map(err => ({
|
|
351
|
+
field: err.path,
|
|
352
|
+
message: err.message
|
|
353
|
+
}))
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// 验证通过,继续处理
|
|
358
|
+
processData(result.data);
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### 实践 3: 抛出异常
|
|
362
|
+
|
|
363
|
+
```javascript
|
|
364
|
+
const result = validator.validate(schema, data);
|
|
365
|
+
|
|
366
|
+
if (!result.valid) {
|
|
367
|
+
const error = new ValidationError(result.errors, data);
|
|
368
|
+
throw error;
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## 性能优化建议
|
|
375
|
+
|
|
376
|
+
### 建议 1: 复用 Validator 实例
|
|
377
|
+
|
|
378
|
+
```javascript
|
|
379
|
+
// ✅ 好:复用实例
|
|
380
|
+
const validator = new Validator();
|
|
381
|
+
|
|
382
|
+
app.post('/api/users', (req, res) => {
|
|
383
|
+
const result = validator.validate(userSchema, req.body);
|
|
384
|
+
// ...
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// ❌ 不好:每次创建新实例
|
|
388
|
+
app.post('/api/users', (req, res) => {
|
|
389
|
+
const validator = new Validator(); // 不推荐
|
|
390
|
+
const result = validator.validate(userSchema, req.body);
|
|
391
|
+
// ...
|
|
392
|
+
});
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 建议 2: 预编译 Schema
|
|
396
|
+
|
|
397
|
+
```javascript
|
|
398
|
+
// 应用启动时预编译
|
|
399
|
+
const validateUser = validator.compile(userSchema);
|
|
400
|
+
const validateProduct = validator.compile(productSchema);
|
|
401
|
+
|
|
402
|
+
// 使用时直接验证(更快)
|
|
403
|
+
app.post('/api/users', (req, res) => {
|
|
404
|
+
const result = validator.validate(validateUser, req.body);
|
|
405
|
+
// ...
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 建议 3: 使用缓存
|
|
410
|
+
|
|
411
|
+
```javascript
|
|
412
|
+
// 显式编译并复用缓存键
|
|
413
|
+
const validateUser = validator.compile(schema, 'user-schema');
|
|
414
|
+
|
|
415
|
+
console.log(validateUser(data));
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 常见问题
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## 对应示例文件
|
|
425
|
+
|
|
426
|
+
**示例入口**: [validate.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/validate.ts)
|
|
427
|
+
**说明**: 覆盖顶层 `validate()` 的成功/失败路径、默认类型转换,以及关闭 `coerce` 后的行为差异。
|
|
428
|
+
|
|
429
|
+
### Q1: 如何验证可选字段?
|
|
430
|
+
|
|
431
|
+
不在 `required` 数组中的字段自动为可选:
|
|
432
|
+
|
|
433
|
+
```javascript
|
|
434
|
+
const schema = {
|
|
435
|
+
type: 'object',
|
|
436
|
+
properties: {
|
|
437
|
+
name: { type: 'string' },
|
|
438
|
+
age: { type: 'number' } // age 是可选的
|
|
439
|
+
},
|
|
440
|
+
required: ['name'] // 只有 name 是必填的
|
|
441
|
+
};
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Q2: 如何允许额外字段?
|
|
445
|
+
|
|
446
|
+
JSON Schema 默认允许额外字段。如果要禁止额外字段:
|
|
447
|
+
|
|
448
|
+
```javascript
|
|
449
|
+
const schema = {
|
|
450
|
+
type: 'object',
|
|
451
|
+
properties: {
|
|
452
|
+
name: { type: 'string' }
|
|
453
|
+
},
|
|
454
|
+
additionalProperties: false // 禁止额外字段
|
|
455
|
+
};
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Q3: 如何验证多种类型?
|
|
459
|
+
|
|
460
|
+
使用 `anyOf` 或 `oneOf`:
|
|
461
|
+
|
|
462
|
+
```javascript
|
|
463
|
+
const schema = {
|
|
464
|
+
type: 'object',
|
|
465
|
+
properties: {
|
|
466
|
+
value: {
|
|
467
|
+
anyOf: [
|
|
468
|
+
{ type: 'string' },
|
|
469
|
+
{ type: 'number' }
|
|
470
|
+
]
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Q4: 性能如何?
|
|
477
|
+
|
|
478
|
+
基于 ajv,业界最快的 JSON Schema 验证器:
|
|
479
|
+
- 验证速度 >15,000 ops/s
|
|
480
|
+
- 内置编译缓存
|
|
481
|
+
- 支持批量验证优化
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## 相关文档
|
|
486
|
+
|
|
487
|
+
- [Validator 类概述](./validator.md)
|
|
488
|
+
- [compile 方法](./compile.md) - 编译 Schema 提升性能
|
|
489
|
+
- [validateBatch 方法](./validate-batch.md) - 批量验证
|
|
490
|
+
- [addKeyword 方法](./add-keyword.md) - 添加自定义验证
|
|
491
|
+
- [JSON Schema 基础](./json-schema-basics.md)
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## 外部参考
|
|
496
|
+
|
|
497
|
+
- [JSON Schema 官方文档](https://json-schema.org/)
|
|
498
|
+
- [ajv 文档](https://ajv.js.org/)
|
|
499
|
+
- [JSON Schema Validator](https://www.jsonschemavalidator.net/) - 在线测试工具
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
**最后更新**: 2025-12-24
|
|
505
|
+
|
|
506
|
+
|