Golang 中的 OpenAPI 规范验证
OpenAPI spec validation in Golang
我想以与此处类似的方式验证 openapi 规范:http://bigstickcarpet.com/swagger-parser/www/index.html 但不同之处在于,我将使用 GO 来编写该工具,它只是一个 CLI。
我正在尝试使用这个:
https://github.com/go-openapi/validate
但主要问题是文档几乎不存在。我来这里是为了寻求以前可能使用过这个库的人的帮助,并且可以给我一个最小的例子,发送一个包含这样的规范的文件,并让这个库以类似于在线 Swagger 验证器的方式抛出所有错误或警告.
我已经可以读取文件并对其中的字段进行一些手动验证,但这当然不是我需要做的,它只是一个示例。
此外,作为次要问题,我想 post 在他们的 GitHub 回购协议中提出同样的问题,但我得到了这个:
而且我不知道如何 "review" 这些指南,所以我可以 post 我的问题。
我有什么:
func validate_spec(spec string) []validator_error {
// RULES HERE. Now I am hardcoding since this is just a dummy app. On the real app we will need to use goapenapi plus a schema validator
var errors []validator_error
name_regex, _ := regexp.Compile("^[a-zA-Z]+[ ][a-zA-Z]+")
// Validate _.name field
if ( ! gjson.Get(spec, "name").Exists() ) {
n := validator_error{Path: "_.name", Message: "Does not exist!"}
errors = append(errors,n)
}
if gjson.Get(spec, "name").Exists() {
if _, ok := gjson.Get(spec, "name").Value().(string); !ok {
n := validator_error{Path: "_.name", Message: "should be a string"}
errors = append(errors,n)
}
if ( ! name_regex.MatchString(gjson.Get(spec, "name").String() ) ) {
n := validator_error{Path: "_.name", Message: "should match " + name_regex.String()}
errors = append(errors,n)
}
}
// ***************************
// Validate _.age field
if ( ! gjson.Get(spec, "age").Exists() ) {
n := validator_error{Path: "_.age", Message: "Does not exist!"}
errors = append(errors,n)
}
if gjson.Get(spec, "age").Exists() {
if _, ok := gjson.Get(spec, "age").Value().(float64); !ok {
n := validator_error{Path: "_.age", Message: "should be an int"}
errors = append(errors,n)
}
}
// ***************************
return errors
}
我需要什么:
func validate_spec(spec string) []validator_error {
// Something like this is what I am looking for. On the above example I am just hard-coding some dummy rules. I need to use the library here to get the validity of the spec being passed.
return goopenapi.validate(spec )
}
我经常使用 https://github.com/go-openapi,发现这些包对于处理 OpenAPI 规范、验证和其他相关内容非常有用。
验证规范本身
看看下面的代码:
document, err = loads.Spec(fpath)
if err != nil {
return nil, errors.Wrap(err, "Failed to load spec")
}
document, err = document.Expanded(&spec.ExpandOptions{RelativeBase: fpath})
if err != nil {
return nil, errors.Wrap(err, "Failed to expand spec")
}
if err := validate.Spec(document, strfmt.Default); err != nil {
return nil, errors.Wrap(err, "Spec is invalid")
}
首先,它加载规范。然后它扩展该规范中的所有引用 ($ref
-s)。之后它会验证规范本身。
按规格验证
所以规范本身是正确的。例如,现在我们要根据该规范验证请求主体。
// sch here is the schema object that can be extracted from
// the spec that you created above.
// data is just an interface{} that represents your data
// structure that you need to validate. data is a struct
// you decoded a json body into like json.Unmarshal(b, &data)
err := validate.AgainstSchema(sch, data, strfmt.Default)
ve, ok := err.(*errors.CompositeError)
// now you can extract errors from ve.Errors
我围绕它构建了 some wrappers 以方便请求验证,例如:
// op here is the OpenAPI operation object that can also be extracted
// from the spec loaded above.
if errs := validate.Body(op.Parameters, body); len(errs) > 0 {
// work with errs
}
免责声明:上面的一些链接指向我不是作者的存储库 oas2 where I am an author and a maintainer. That repository is build on top of go-openapi。
我发现 kin-openapi 提供了最接近我正在寻找的抽象级别的东西。也就是说,我只想根据规范验证我的 http 请求和响应,而不将其分解为多个部分(查询参数、路径参数、正文等)。它不是 相当 到这个抽象级别,但我有一个开放的 PR。不确定它是否会被接受,但它仍然是您自己冒险的一个很好的起点!
我想以与此处类似的方式验证 openapi 规范:http://bigstickcarpet.com/swagger-parser/www/index.html 但不同之处在于,我将使用 GO 来编写该工具,它只是一个 CLI。
我正在尝试使用这个:
https://github.com/go-openapi/validate
但主要问题是文档几乎不存在。我来这里是为了寻求以前可能使用过这个库的人的帮助,并且可以给我一个最小的例子,发送一个包含这样的规范的文件,并让这个库以类似于在线 Swagger 验证器的方式抛出所有错误或警告.
我已经可以读取文件并对其中的字段进行一些手动验证,但这当然不是我需要做的,它只是一个示例。
此外,作为次要问题,我想 post 在他们的 GitHub 回购协议中提出同样的问题,但我得到了这个:
而且我不知道如何 "review" 这些指南,所以我可以 post 我的问题。
我有什么:
func validate_spec(spec string) []validator_error {
// RULES HERE. Now I am hardcoding since this is just a dummy app. On the real app we will need to use goapenapi plus a schema validator
var errors []validator_error
name_regex, _ := regexp.Compile("^[a-zA-Z]+[ ][a-zA-Z]+")
// Validate _.name field
if ( ! gjson.Get(spec, "name").Exists() ) {
n := validator_error{Path: "_.name", Message: "Does not exist!"}
errors = append(errors,n)
}
if gjson.Get(spec, "name").Exists() {
if _, ok := gjson.Get(spec, "name").Value().(string); !ok {
n := validator_error{Path: "_.name", Message: "should be a string"}
errors = append(errors,n)
}
if ( ! name_regex.MatchString(gjson.Get(spec, "name").String() ) ) {
n := validator_error{Path: "_.name", Message: "should match " + name_regex.String()}
errors = append(errors,n)
}
}
// ***************************
// Validate _.age field
if ( ! gjson.Get(spec, "age").Exists() ) {
n := validator_error{Path: "_.age", Message: "Does not exist!"}
errors = append(errors,n)
}
if gjson.Get(spec, "age").Exists() {
if _, ok := gjson.Get(spec, "age").Value().(float64); !ok {
n := validator_error{Path: "_.age", Message: "should be an int"}
errors = append(errors,n)
}
}
// ***************************
return errors
}
我需要什么:
func validate_spec(spec string) []validator_error {
// Something like this is what I am looking for. On the above example I am just hard-coding some dummy rules. I need to use the library here to get the validity of the spec being passed.
return goopenapi.validate(spec )
}
我经常使用 https://github.com/go-openapi,发现这些包对于处理 OpenAPI 规范、验证和其他相关内容非常有用。
验证规范本身
看看下面的代码:
document, err = loads.Spec(fpath)
if err != nil {
return nil, errors.Wrap(err, "Failed to load spec")
}
document, err = document.Expanded(&spec.ExpandOptions{RelativeBase: fpath})
if err != nil {
return nil, errors.Wrap(err, "Failed to expand spec")
}
if err := validate.Spec(document, strfmt.Default); err != nil {
return nil, errors.Wrap(err, "Spec is invalid")
}
首先,它加载规范。然后它扩展该规范中的所有引用 ($ref
-s)。之后它会验证规范本身。
按规格验证
所以规范本身是正确的。例如,现在我们要根据该规范验证请求主体。
// sch here is the schema object that can be extracted from
// the spec that you created above.
// data is just an interface{} that represents your data
// structure that you need to validate. data is a struct
// you decoded a json body into like json.Unmarshal(b, &data)
err := validate.AgainstSchema(sch, data, strfmt.Default)
ve, ok := err.(*errors.CompositeError)
// now you can extract errors from ve.Errors
我围绕它构建了 some wrappers 以方便请求验证,例如:
// op here is the OpenAPI operation object that can also be extracted
// from the spec loaded above.
if errs := validate.Body(op.Parameters, body); len(errs) > 0 {
// work with errs
}
免责声明:上面的一些链接指向我不是作者的存储库 oas2 where I am an author and a maintainer. That repository is build on top of go-openapi。
我发现 kin-openapi 提供了最接近我正在寻找的抽象级别的东西。也就是说,我只想根据规范验证我的 http 请求和响应,而不将其分解为多个部分(查询参数、路径参数、正文等)。它不是 相当 到这个抽象级别,但我有一个开放的 PR。不确定它是否会被接受,但它仍然是您自己冒险的一个很好的起点!