golang快速实现JSON Schema表达式匹配插件库schema的使用
Golang快速实现JSON Schema表达式匹配插件库schema的使用
schema库可以更方便地检查map/array结构是否匹配特定模式,非常适合测试JSON API或验证传入请求的格式并向API用户提供错误消息。
安装
go get github.com/jgroeneveld/schema
基本使用示例
func TestJSON(t *testing.T) {
// 假设这是从API获取的JSON响应
reader := strings.NewReader(`{
"id": 12,
"name": "Max Mustermann",
"age": 42,
"height": 1.91,
"footsize": 43,
"address": {
"street": "Main St",
"zip": "12345"
},
"tags": ["red", "blue"]
}`)
// 定义schema匹配规则
err := schema.MatchJSON(
schema.Map{
"id": schema.IsInteger, // 必须是整数
"name": "Max Mustermann", // 必须完全匹配这个字符串
"age": 42, // 必须等于42
"height": schema.IsFloat, // 必须是浮点数
"footsize": schema.IsPresent, // 必须存在这个字段
"address": schema.Map{ // 嵌套map结构
"street": schema.IsString, // 必须是字符串
"zip": schema.IsString, // 必须是字符串
},
"tags": schema.ArrayIncluding("red"), // 数组必须包含"red"
},
reader,
)
if err != nil {
t.Fatal(err)
}
}
主要入口点
// 匹配任意数据结构
schema.Match(schema.Matcher, interface{}) error
// 直接从JSON Reader匹配
schema.MatchJSON(schema.Matcher, io.Reader) error
常用匹配器
-
具体值:任何具体值如"Name", 12, true, false, nil
-
IsPresent:值是否存在(空字符串也算存在)
-
类型检查:
- IsString
- IsInt
- IsFloat
- IsBool
- IsTime(format)
-
Map匹配器:
// 必须完全匹配所有键和值,不允许额外键 schema.Map{"key": Matcher, ...} // 只检查给定的键和值,忽略额外键 schema.MapIncluding{"key": Matcher, ...}
-
数组匹配器:
// 按顺序匹配所有数组元素 schema.Array(Matcher...) // 匹配所有数组元素但忽略顺序 schema.ArrayUnordered(Matcher...) // 报告无法匹配的元素 schema.ArrayIncluding(Matcher...) // 每个数组元素都必须匹配给定的匹配器 schema.ArrayEach(Matcher)
自定义匹配器
你可以实现自己的匹配器:
// 检查RFC3339格式的时间字符串
var IsTime = schema.MatcherFunc("IsTime",
func(data interface{}) *schema.Error {
s, ok := data.(string)
if !ok {
return schema.SelfError("不是有效时间: 不是字符串")
}
_, err := time.Parse(time.RFC3339, s)
if err != nil {
return schema.SelfError("不是有效时间: " + err.Error())
}
return nil
},
)
// 更通用的时间格式匹配器
func IsTime(format string) schema.Matcher {
return schema.MatcherFunc("IsTime",
func(data interface{}) *schema.Error {
s, ok := data.(string)
if !ok {
return schema.SelfError("不是有效时间: 不是字符串")
}
_, err := time.Parse(format, s)
if err != nil {
return schema.SelfError("不是有效时间: " + err.Error())
}
return nil
},
)
}
错误处理
当匹配失败时,schema会返回详细的错误信息。例如对于以下JSON输入:
{
"id": 12,
"name": "Hans Meier",
"age": 42,
"height": 1.91,
"address": {
"street": 12
},
"tags": ["blue", "green"]
}
错误输出会是:
"address": Missing keys: "zip"
"address.street": is no string but float64
"name": "Hans Meier" != "Max Mustermann"
"tags": red:string(0) not included
Missing keys: "footsize"
注意事项
-
数字处理:JSON不区分整数和浮点数,Go的JSON库在解析到interface{}时总是返回float64,这可能导致一些边界情况。
-
数组匹配器:数组匹配器会先匹配具体值,再匹配通用匹配器,最后匹配IsPresent,这种顺序可能在某些复杂嵌套结构中不适用。
schema库提供了简单直观的方式来验证JSON结构,特别适合API测试和请求验证场景。
更多关于golang快速实现JSON Schema表达式匹配插件库schema的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复