donlih2986 2018-02-12 18:14
浏览 278
已采纳

Golang中的OpenAPI规范验证

I want to validate an openapi spec in a similar fashion as its done here : http://bigstickcarpet.com/swagger-parser/www/index.html but the difference is that Ill use GO to code the tool and its only a CLI.

I am trying to use this :

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

But the main problem is that the documentation is almost non existent. I came here looking for help of someone that might previously used this library and can give me a MINIMAL example of sending a file containing a spec like such and having this library to throw all the errors or warnings in a similar fashion to the online Swagger validator.

I already can read a file and do some manual validation of the fields on it but of course thats not what I need to do and its just a sample.

Additionally, as a secondary question, I want to post this same question on their GitHub repo but I get this :

enter image description here

and I have no idea how to "review" these guidelines so I can post my question.

What I have :

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
}

What I need :

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 )
    }
  • 写回答

1条回答 默认 最新

  • dongzuo9096 2018-02-15 10:29
    关注

    I use https://github.com/go-openapi quite a lot and find that packages very useful to work with OpenAPI spec, validations and other related stuff.

    Validate the spec itself

    Take a look at the following code:

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

    First of all, it loads spec. Then it expands all references ($ref-s) in that spec. After that it validates the spec itself.

    Validate by spec

    So the spec itself is correct. Now we want to validate, for example, a request body by that spec.

    // 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
    

    I've build some wrappers around it for easy request validations, for example:

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

    Disclaimer: Some links above lead to the repository oas2 where I am an author and a maintainer. That repository is build on top of go-openapi where I am not the author.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题