3 个不稳定版本
0.2.1 | 2021年2月1日 |
---|---|
0.2.0-test.2 | 2021年2月1日 |
0.1.0 | 2020年4月26日 |
#3 in #infer
42KB
698 行
jtd-infer: 从示例生成 JSON 类型定义模式
JSON 类型定义,又称 RFC8927,是一种易于学习、标准化的方式,用于定义 JSON 数据的模式。您可以使用 JSON 类型定义在不同的编程语言之间可移植地验证数据、创建占位符数据、生成代码等。
jtd-infer
是一个工具,可以从示例数据生成(推断)JSON 类型定义模式。
echo '{ "name": "Joe", "age": 42 }' | jtd-infer | jq
{
"properties": {
"age": {
"type": "uint8"
},
"name": {
"type": "string"
}
}
}
安装
在 macOS 上,您可以通过 Homebrew 安装 jtd-infer
。
brew install jsontypedef/jsontypedef/jtd-infer
对于所有其他平台,您可以从 最新版本 下载并解压二进制文件。您还可以通过运行 cargo
来安装。
cargo install jtd_infer
用法
有关如何使用 jtd-infer
的高级指导,请参阅 JSON 类型定义网站文档中的 "从实际数据推断 JSON 类型定义模式"。
基本用法
要调用 jtd-infer
,您可以
- 让它从 STDIN 读取。这是默认行为。
- 让它从一个文件读取。为此,将文件名作为
jtd-infer
的最后一个参数传递。
jtd-infer
读取一个 序列 的 JSON 消息。例如,如果您有一个如下所示的 data.json
文件:
{ "name": "john doe", "age": 42 }
{ "name": "jane doe", "age": 45 }
您可以通过两种方式将其提供给 jtd-infer
# Both of these do the same thing.
cat data.json | jtd-infer
jtd-infer data.json
在这两种情况下,您都会得到这个输出
{"properties":{"name":{"type":"string"},"age":{"type":"uint8"}}}
更改默认数字类型
⚠️ 此部分通常在您将 JSON 类型定义应用到基于 JavaScript 的应用程序时很重要。
默认情况下,JSON 类型定义将推断输入的最具体可能类型。例如,如果您在输入中看到 12
,它会猜测 uint8
。
echo "12" | jtd-infer
{"type":"uint8"}
但是,如果您只向 JSON 类型定义提供了一个小的样本集,或者实际上您有远小于应用程序支持的实际数值数据类型的数据,那么这种行为可能是不希望的。例如,基于 JavaScript 的应用程序通常对所有数值输入都支持 float64
,因为 JavaScript 的数字是 IEEE 双精度浮点数。
要告诉 JSON 类型定义使用与其通常猜测不同的类型,您可以使用 --default-number-type
来更改其行为。例如:
# JavaScript numbers are all float64s, and so it's pretty common for JavaScript
# applications to not check if inputs are integers or within a particular range.
#
# If you don't want to make your JSON Typedef schema strict about decimal,
# negative, or out of int range numbers, you can pass float64 as the default
# number type.
echo "12" | jtd-infer --default-number-type=float64
{"type":"float64"}
另一个用例是如果你正在编写一个使用签名字符串32位整数的应用程序,并且你的示例数据实际上从不包含负数或超过8位或16位数字的数字。你可以通过将 int32
作为默认数字类型来实现这一点。
echo "12" | jtd-infer --default-number-type=int32
{"type":"int32"}
请注意,如果 jtd-infer
的默认值与数据不匹配,它将忽略默认值。例如,int32
只与整数一起工作,因此如果出现小数或32位有符号整数无法表示的数字,它将回退到 float64
。
# both of these output {"type":"float64"}
echo "3.14" | jtd-infer --default-number-type=int32
echo "9999999999" | jtd-infer --default-number-type=int32
高级使用:提供提示
默认情况下,jtd-infer
从不输出 enum
、values
或 discriminator
架构。这是设计决定的:通过始终与其输出保持一致,jtd-infer
更可预测和可靠。
如果你想让 jtd-infer
输出 enum
、values
或 discriminator
,你可以使用 --enum-hint
、--values-hint
和 --discriminator-hint
标志。你可以多次传递这些标志。
所有提示标志都接受 JSON Pointers 作为值。如果你习惯于使用类似于 JavaScript 的语法来引用事物,如 $.foo.bar
,则相应的 JSON Pointer 为 /foo/bar
。 jtd-infer
将 -
视为“通配符”。 /foo/-/bar
等同于 JavaScript-y 的 $.foo.*.bar
。
作为一个特殊情况,如果你想指向输入的 根 / 顶级,那么请使用空字符串作为路径。有关示例,请参阅 "使用 --values-hint
"。
使用 --enum-hint
默认情况下,字符串总是推断为 { "type": "string" }
echo '["foo", "bar", "baz"]' | jtd-infer
{"elements":{"type":"string"}}
但是,你可以通过提供指向你认为属于枚举的字符串的路径来让 jtd-infer
输出枚举。在这种情况下,它是数组的根元素中的任何元素--相应的 JSON Pointer 为 /-
echo '["foo", "bar", "baz"]' | jtd-infer --enum-hint=/-
{"elements":{"enum":["bar","baz","foo"]}}
使用 --values-hint
默认情况下,对象总是假设为 "struct",并且 jtd-infer
将生成 properties
/ optionalProperties
。例如
echo '{"x": [1, 2, 3], "y": [4, 5, 6], "z": [7, 8, 9]}' | jtd-infer
{"properties":{"y":{"elements":{"type":"uint8"}},"z":{"elements":{"type":"uint8"}},"x":{"elements":{"type":"uint8"}}}}
如果你的数据更像是映射/字典,请传递一个指向你想要获取 values
架构的对象的 values-hint
。在这种情况下,它是顶层对象,在 JSON Pointer 中只是一个空字符串
echo '{"x": [1, 2, 3], "y": [4, 5, 6], "z": [7, 8, 9]}' | jtd-infer --values-hint=
{"values":{"elements":{"type":"uint8"}}}
使用 --discriminator-hint
默认情况下,对象总是假设为 "struct",并且 jtd-infer
将生成 properties
/ optionalProperties
。例如
echo '[{"type": "s", "value": "foo"},{"type": "n", "value": 3.14}]' | jtd-infer
{"elements":{"properties":{"value":{},"type":{"type":"string"}}}}
如果你的数据有一个特殊的 "type" 属性,该属性告诉你对象中有什么,那么请使用 --discriminator-hint
来指向该属性。 jtd-infer
将输出适当的 discriminator
架构
echo '[{"type": "s", "value": "foo"},{"type": "n", "value": 3.14}]' | jtd-infer --discriminator-hint=/-/type | jq
{
"elements": {
"discriminator": "type",
"mapping": {
"s": {
"properties": {
"value": {
"type": "string"
}
}
},
"n": {
"properties": {
"value": {
"type": "float64"
}
}
}
}
}
}
依赖关系
~2.6–4MB
~67K SLoC