Golang中的openapi规范验证

时间:2018-02-12 18:14:16

标签: go specifications openapi

我想以与此处完成的方式类似的方式验证openapi规范:http://bigstickcarpet.com/swagger-parser/www/index.html但不同之处在于我使用GO来编写工具代码并且只使用CLI。

我正在尝试使用它:

https://github.com/go-openapi/validate

但主要问题是文档几乎不存在。我来到这里寻找以前可能使用过这个库的人的帮助,并且可以给我一个MINIMAL示例,发送一个包含类似规范的文件,并让这个库以与在线Swagger验证器类似的方式抛出所有错误或警告

我已经可以读取文件并对其中的字段进行一些手动验证,但当然这不是我需要做的,只是一个样本。

此外,作为第二个问题,我想在他们的GitHub回购中发布同样的问题,但我明白了:

enter image description here

我不知道如何“审核”这些指南,以便发表我的问题。

我拥有的是什么:

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 )
    }

2 个答案:

答案 0 :(得分:9)

我使用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")
}

首先,它加载spec。然后它扩展了该规范中的所有引用($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,我是作者和维护者。该存储库建立在go-openapi之上,我不是作者。

答案 1 :(得分:0)

我发现kin-openapi提供了与我想要的抽象级别最接近的东西。也就是说,我只想根据规范验证我的http请求和响应,而无需将其分解成几个部分(查询参数,路径参数,正文等)。在这个抽象水平上,它还不是相当,但是我有一个开放的PR。不确定是否会接受它,但是它仍然是您自己冒险的一个很好的起点!