Eskema 是一个可以帮助您使用简单但功能强大的 API 验证动态数据的工具。
它最初的目的是验证来自 API 的动态 JSON,由用户输入或您可能需要验证动态数据的任何其他场景。但它并不局限于 JSON 数据,您可以验证任何类型的动态数据。
特点
- 简单的API
- 可组合 / 可扩展
- Safe
- 完全测试
入门
要使用此包,除了安装包或将其添加到 pubspec.yml 中,没有太多其他工作要做。有关如何操作的指南,请查看 安装说明
概念
验证器
Eskema 中的几乎所有内容都是 [验证器],它们是接收一个值并返回一个 [IResult] 的函数。
以下都是验证器
isType<String>();
listOfLength(2);
listEach(isType<String>());
all([isType<List>(), isListOfLength(2)]);
IResult
这是一个表示验证结果的类
用法
一个例子胜过千言万语,所以这里有几个简单的例子。
有关更详细的示例,请查看 /examples 文件夹。
简单示例
注意:如果您只想验证单个值,您可能不需要 Eskema。
否则,让我们看看如何验证单个值。您可以单独使用验证器
final isString = isType<String>();
const result1 = isString('valid string');
const result2 = isString(123);
result1.isValid; // true
result2.isValid; // false
result2.expected; // String
或者您可以组合使用验证器
all([isType<String>(), isDate()]); // all validators must be valid
or(isType<String>(), isType<int>()); // either validator must be valid
and(isType<String>(), isType<int>()); // both validator must be valid
// This validator checks that, the value is a list of strings, with length 2, and contains item "test"
all([
isOfLength(2), // checks that the list is of length 2
listEach(isTypeOrNull<String>()), // checks that each item is either string or null
listContains('test'), // list must contain value "test"
]);
// This validator checks a map against a eskema. Map must contain property 'books',
// which is a list of maps that matches a sub-eskema. Subeskema validates that the map has a name which is a string
final matchesEskema = eskema({
'books': listEach(
eskema({
'name': isType<String>(),
}),
),
});
matchesEskema({'books': [{'name': 'book name'}]});
验证器
isType
此验证器检查值是否为特定类型
isType<String>();
isType<int>();
isType<double>();
isType<List>();
isType<Map>();
isTypeOrNull
此验证器检查值是否为特定类型或为 null
isTypeOrNull<String>();
isTypeOrNull<int>();
nullable
此验证器允许验证器接受 null 值
nullable(eskema({...}));
- 上面的验证器允许 Map 或 null
eskema
最常见的用例可能是验证 JSON 或动态 Map。为此,您可以使用 eskema 验证器。
在此示例中,我们验证了一个具有可选字段和嵌套字段的 Map。
final validateMap = eskema({
'name': isTypeString(),
'address': nullable(
eskema({
'city': isTypeString(),
'street': isTypeString(),
'number': all([
isTypeInt(),
isMin(0),
]),
'additional': nullable(
eskema({
'doorbel_number': Field([isTypeInt()])
})
),
})
)
});
final invalidResult = validateMap.call({});
invalidResult.isValid; // false
invalidResult.isNotValid; // true
invalidResult.expected; // name -> String
invalidResult.message; // Expected name -> String
final validResult = validateMap.call({ 'name': 'bobby' });
validResult.isValid; // true
validResult.isNotValid; // false
validResult.expected; // Valid
listEach
另一个常见的用例是验证动态 List。为此,您可以使用 listEach 类。
此示例验证提供的值是一个长度为 2 的 List,并且每个元素都必须是 int 类型
final isValidList = all([
listOfLength(2),
listEach(isTypeInt()),
]);
isValidList.validate(null).isValid; // true
isValidList.validate([]).isValid; // true
isValidList.validate([1, 2]).isValid; // true
isValidList.validate([1, "2"]).isValid; // false
isValidList.validate([1, "2"]).expected; // [1] -> int
附加验证器
有关验证器的完整列表,请查看 文档
自定义验证器
Eskema 在 lib/src/validators.dart 中提供了一组常见的验证器。您不仅限于使用这些验证器,还可以非常轻松地创建自定义验证器。
让我们看看如何创建一个验证器来检查字符串是否匹配某个模式
Validator validateRegexp(RegExp regexp) {
return (value) {
return Result(
isValid: regexp.hasMatch(value),
expected: 'match pattern $regexp', // the message explaining what this validator expected
);
};
}
如果您希望您构建的验证器成为包的一部分,请发送一个 PR,我会考虑添加它!!
更多示例
有关更多示例,请查看 /examples 文件夹。或者查看 文档
包名
Eskema 是巴斯克语中“Schema”(模式)的意思。我不知道该给包起什么名字,经过一番寻找,我找到了巴斯克语中“schema”的词,并决定使用它!