Skip to main content
版本: 0.4.3

校验

使用 KCL 校验数据

除了使用 KCL 代码生成 JSON/YAML 等配置格式,KCL 还支持对 JSON/YAML 数据进行格式校验。作为一种配置语言,KCL 在验证方面几乎涵盖了 OpenAPI 的所有功能。在 KCL 中可以通过一个结构定义来约束配置数据,同时支持通过 check 块自定义约束规则,在 schema 中书写校验表达式对 schema 定义的属性进行校验和约束。通过 check 表达式可以非常清晰简单地校验输入的 JSON/YAML 是否满足相应的 schema 结构定义与 check 约束。

简介

在 schema 定义当中可以使用 check 关键字编写 schema 属性的校验规则, 如下所示,check 代码块中的每一行都对应一个条件表达式,当满足条件时校验成功,当不满足条件时校验失败。条件表达式后可跟 , "check error message" 表示当校验失败时需要显示的信息。

import regex

schema Sample:
foo: str # Required, 不能为None/Undefined, 且类型必须为str
bar: int # Required, 不能为None/Undefined, 且类型必须为int
fooList: [int] # Required, 不能为None/Undefined, 且类型必须为int列表
color: "Red" | "Yellow" | "Blue" # Required, 字面值联合类型,且必须为"Red", "Yellow", "Blue"中的一个,枚举作用
id?: int # Optional,可以留空,类型必须为int

check:
0 <= bar < 100 # bar必须大于等于0,小于100
0 < len(fooList) < 100 # fooList不能为None/Undefined,并且长度必须大于0,小于100
regex.match(foo, "^The.*Foo$") # regex 正则表达式匹配
bar in range(100) # range, bar范围只能为1到99
bar in [2, 4, 6, 8] # enum, bar只能取2, 4, 6, 8
bar % 2 == 0 # bar必须为2的倍数
all foo in fooList {
foo > 1
} # fooList中的所有元素必须大于1
any foo in fooList {
foo > 10
} # fooList中至少有一个元素必须大于10
abs(id) > 10 if id # check if 表达式,当 id 不为空时,id的绝对值必须大于10

综上所述,KCL Schema 中支持的校验类型为:

校验类型使用方法
范围校验使用 <, > 等比较运算符
正则校验使用 regex 系统库中的 match 等方法
长度校验使用 len 内置函数,可以求 list/dict/str 类型的变量长度
枚举校验使用字面值联合类型
非空校验使用 schema 的可选/必选属性
条件校验使用 check if 条件表达式

基于此,KCL 提供了相应的校验工具 直接对 JSON/YAML 数据进行校验。此外,通过 KCL schema 的 check 表达式可以非常清晰简单地校验输入的 JSON 是否满足相应的 schema 结构定义与 check 约束。

如何使用

新建一个名为 data.json 的 JSON 配置文件:

{
"name": "Alice",
"age": "18",
"message": "This is Alice",
"data": {
"id": "1",
"value": "value1"
},
"labels": {
"key": "value"
},
"hc": [1, 2, 3]
}

构建一个用于校验上述 JSON 文件的 KCL 文件 schema.k

schema User:
name: str
age: int
message?: str
data: Data
labels: {str:}
hc: [int]

check:
age > 10

schema Data:
id: int
value: str

执行如下命令获得校验结果

$ kcl-vet data.json schema.k
Validate succuss!

未来计划

KCL 校验能力的提升将逐渐围绕"静态化"方面展开工作,即在编译时,结合形式化验证的能力直接分析得出数据是否满足约束条件、约束条件是否冲突等结论,并且可以通过 IDE 实时透出约束错误,而无需在运行时发现错误。