Ajv不仅仅可以校验json,也可以修改校验值
前言
写代码时需要实现用ajv,jsonschema的方式入参进行校验并修改格式,最后返回出去。我搜了很久发现没有前辈记录这个,让我以为ajv只能进行校验,无法修改,最后看了官方文档才发现居然可以对值进行修改甚至改类型。
一、官方文档链接
https://ajv.js.org/guide/modifying-data.html
二、几个修改数据的选项
1.removeAdditional
移除schema中未定义的属性,初始化Ajv时加入选项removeAdditional:true
const ajv = new Ajv({removeAdditional: true})
const schema = {
additionalProperties: false,
properties: {
foo: {type: "number"},
bar: {
additionalProperties: {type: "number"},
properties: {
baz: {type: "string"},
},
},
},
}
const data = {
foo: 0,
additional1: 1, // will be removed; `additionalProperties` == false
bar: {
baz: "abc",
additional2: 2, // will NOT be removed; `additionalProperties` != false
},
}
const validate = ajv.compile(schema)
console.log(validate(data)) // true
console.log(data) // { "foo": 0, "bar": { "baz": "abc", "additional2": 2 }
2.Assigning defaults
用schema中定义的属性如果缺失了,就用默认值去覆盖对应的属性。null和""都被认为是缺失。
Example1 default in properties
const ajv = new Ajv({useDefaults: true})
const schema = {
type: "object",
properties: {
foo: {type: "number"},
bar: {type: "string", default: "baz"},
},
required: ["foo", "bar"],
}
const data = {foo: 1}
const validate = ajv.compile(schema)
console.log(validate(data)) // true
console.log(data) // { "foo": 1, "bar": "baz" }
Example1 default in properties
const schema = {
type: "array",
items: [{type: "number"}, {type: "string", default: "foo"}],
}
const data = [1]
const validate = ajv.compile(schema)
console.log(validate(data)) // true
console.log(data) // [ 1, "foo" ]
如果使用了useDefaults属性,当default关键字满足以下情况会抛错:
- 不在properties或items或它们的子对象中
- 在anyOf/oneOf/not/if中
- 在用户自定义的宏关键字(macro keywords)
3.Coercing data types
强转数据类型
Example1
const ajv = new Ajv({coerceTypes: true})
const schema = {
type: "object",
properties: {
foo: {type: "number"},
bar: {type: "boolean"},
},
required: ["foo", "bar"],
}
const data = {foo: "1", bar: "false"}
const validate = ajv.compile(schema)
console.log(validate(data)) // true
console.log(data) // { "foo": 1, "bar": false }
Example 2 (array coercions):
const ajv = new Ajv({coerceTypes: "array"})
const schema = {
properties: {
foo: {type: "array", items: {type: "number"}},
bar: {type: "boolean"},
},
}
const data = {foo: "1", bar: ["false"]}
const validate = ajv.compile(schema)
console.log(validate(data)) // true
console.log(data) // { "foo": [1], "bar": false }