You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go-Swagger中如何自定义校验器并在Swagger规范中使用?

实现Go-Swagger自定义字符串格式校验器

要实现和strfmt.UUID、strfmt.ObjectId一致的自定义格式校验,需完成以下核心步骤:

1. 定义自定义格式类型并实现校验逻辑

创建底层为string的自定义类型,实现strfmt.Validator接口(要求实现Validate() error方法),同时实现序列化/反序列化接口确保数据处理正常:

package yourpackage

import (
    "github.com/go-openapi/strfmt"
    "github.com/go-openapi/swag"
    "github.com/hashicorp/go-multierror"
    "unicode"
)

// Login 自定义登录名格式类型
type Login string

// Validate 实现strfmt.Validator接口,调用自定义校验逻辑
func (l Login) Validate() error {
    return ValidateLogin(string(l))
}

// MarshalText 实现序列化接口
func (l Login) MarshalText() ([]byte, error) {
    return []byte(l), nil
}

// UnmarshalText 实现反序列化接口,反序列化时自动触发校验
func (l *Login) UnmarshalText(data []byte) error {
    *l = Login(data)
    return l.Validate()
}

// Password 自定义密码格式类型
type Password string

// Validate 实现strfmt.Validator接口
func (p Password) Validate() error {
    return ValidatePassword(string(p))
}

// MarshalText 实现序列化接口
func (p Password) MarshalText() ([]byte, error) {
    return []byte(p), nil
}

// UnmarshalText 实现反序列化接口
func (p *Password) UnmarshalText(data []byte) error {
    *p = Password(data)
    return p.Validate()
}

// 自定义登录名校验函数
func ValidateLogin(s string) error {
    var err error
    if len(s) == 0 {
        err = multierr.Append(err, swag.RequiredError("login", "string"))
    }
    if len(s) < 8 {
        err = multierr.Append(err, swag.MinLengthError("login", 8, len(s)))
    }
    for _, r := range s {
        if !unicode.IsLetter(r) && !unicode.IsNumber(r) || r >= unicode.MaxASCII {
            err = multierr.Append(err, swag.InvalidTypeError("login", "alphanumeric ASCII", r))
        }
    }
    return err
}

// 自定义密码校验函数
func ValidatePassword(pass string) error {
    var err error
    if len(pass) == 0 {
        err = multierr.Append(err, swag.RequiredError("password", "string"))
    }
    if len(pass) < 8 {
        err = multierr.Append(err, swag.MinLengthError("password", 8, len(pass)))
    }

    var upp, low, num, sym bool
    for _, char := range pass {
        switch {
        case unicode.IsUpper(char):
            upp = true
        case unicode.IsLower(char):
            low = true
        case unicode.IsNumber(char):
            num = true
        case unicode.IsPunct(char) || unicode.IsSymbol(char):
            sym = true
        default:
            err = multierr.Append(err, swag.InvalidTypeError("password", "upper/lower/number/symbol", char))
        }
    }
    if !upp {
        err = multierr.Append(err, swag.RequiredError("password", "uppercase character"))
    }
    if !low {
        err = multierr.Append(err, swag.RequiredError("password", "lowercase character"))
    }
    if !num {
        err = multierr.Append(err, swag.RequiredError("password", "numeric character"))
    }
    if !sym {
        err = multierr.Append(err, swag.RequiredError("password", "symbol/punctuation character"))
    }
    return err
}

2. 注册自定义格式到strfmt注册表

在程序启动阶段(比如init()函数),将自定义格式注册到strfmt.Default注册表,让go-swagger的校验器能识别这些格式:

package yourpackage

import "github.com/go-openapi/strfmt"

func init() {
    // 注册login格式,关联到Login类型
    strfmt.Default.Add("login", func() strfmt.Formatter { return new(Login) })
    // 注册password格式,关联到Password类型
    strfmt.Default.Add("password", func() strfmt.Formatter { return new(Password) })
}

3. 配置Swagger规范

在Swagger YAML/JSON中直接使用自定义format字段,名称需和注册的格式名一致:

components:
  schemas:
    Credentials:
      type: object
      properties:
        login:
          type: string
          format: login
        password:
          type: string
          format: password
      required: [login, password]

4. 生成代码时关联自定义类型

使用swagger generate server/client命令生成代码时,通过两种方式关联自定义类型:

方式1:命令行参数指定模型包

swagger generate server -f swagger.yml --model-package yourpackage/models

方式2:Swagger规范中添加x-go-type扩展

如果自定义类型不在默认生成的模型包中,可在schema里明确指定:

login:
  type: string
  format: login
  x-go-type:
    type: Login
    import:
      package: yourpackage

5. 验证效果

代码生成后,API接收请求时会自动将login、password字段反序列化为自定义类型,并触发Validate()方法执行校验逻辑。校验不通过时,会返回标准的API错误响应。


内容的提问来源于stack exchange,提问作者fpawel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 03:55:39