前回のブログ投稿のステートメントには問題があります。バインディング全体は gin プロジェクトではなく、依然として go-playground/validator 検証システムを使用しています。
package binding
import (
"reflect"
"sync"
"github.com/go-playground/validator/v10"
)
type defaultValidator struct {
once sync.Once
validate *validator.Validate
}
var _ StructValidator = &defaultValidator{}
// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
func (v *defaultValidator) ValidateStruct(obj interface{}) error {
value := reflect.ValueOf(obj)
valueType := value.Kind()
if valueType == reflect.Ptr {
valueType = value.Elem().Kind()
}
if valueType == reflect.Struct {
v.lazyinit()
if err := v.validate.Struct(obj); err != nil {
return err
}
}
return nil
}
したがって、go-playground/validator のソースコードも使用して整理する必要があります。コード内の go ファイルは pt.go で、次のように構成されています。
キーワード | 目標 | 関数 | 例 |
必要 | プロパティ、構造、ファイル | フラグが存在する必要があります | `検証:"必須"` |
レン | 文字列、配列、時間間隔、ファイル長 | マークの長さ、大きさ、間隔、大きさ | `検証:"len=1"` |
分 | 文字列、数値、配列、時間間隔 | 最小のものをマークします | `検証:"min=1"` |
最大 | 文字列、数値、配列、時間 | 最大値をマークします | `検証:"最大=7"` |
等価 | 文字列、配列、間隔、ブール値 | 等しいことを示し、反対側の配列が長さになります | `検証:"eq=3"` |
それはです | 文字列、配列、間隔、ブール値 | 不平等なマークを付ける | `検証:"ne="` |
それ | 文字列、数値、配列、時間 | 未満 | `検証:"lt=3"` |
LTE | 文字列、数値、配列、時間 | 以下 | `検証:"lte=3"` |
GT | 文字列、数値、配列、時間 | 以上 | `検証:"gt=3"` |
ジーテ | 文字列、数値、配列、時間 | 以上 | `検証:"gte=3"` |
エクフィールド | 兄弟属性 | 同等 | `validate:"eqfield=MaxString"` |
エクシーズフィールド | 内部プロパティ | 同等 | `validate:"eqcsfield=Inner.EqCSFieldString"` |
ネックスフィールド | 内部プロパティ | 等しくない | `validate:"necsfield=Inner.NeCSFieldString"` |
gtcsフィールド | 内部プロパティ | 以上 | `validate:"gtcsfield=Inner.GtCSFieldString"` |
LTCSフィールド | 内部プロパティ | 未満 | `validate:"ltcsfield=Inner.LtCSFieldString"` |
テクスフィールド | 内部プロパティ | 以下 | `validate:"ltecsfield=Inner.LteCSFieldString"` |
ネフィールド | 兄弟属性 | 等しくない | `validate:"nefield=EqFieldString"` |
GTフィールド | 兄弟属性 | 以上 | `validate:"gtfield=MaxString"` |
ジーテフィールド | 兄弟属性 | 以上 | `validate:"gtefield=MaxString"` |
LTフィールド | 兄弟属性 | 未満 | `validate:"ltfield=MaxString"` |
LTEフィールド | 兄弟属性 | 以下 | `validate:"ltefield=MaxString"` |
アルファ | 弦 | "^[a-zA-Z]+$" | `検証:"アルファ"` |
アルファナム | 弦 | "^[a-zA-Z0-9]+$" | `validate:"alphanum"` |
数値 | 弦 | "^[-+]?[0-9]+(?: \\ .[0-9]+)?$" | `検証:"数値"` |
番号 | 弦 | "^[0-9]+$" | `検証:"数値"` |
16進数 | 弦 | "^(0[xX])?[0-9a-fA-F]+$" | `検証:"16 進数"` |
六色 | 弦 | "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" | `検証:"hexcolor"` |
RGB | 弦 | 複雑な正規表現は表示されません | `検証:"rgb"` |
rgba | 弦 | 複雑な正規表現は表示されません | |
hsl | 弦 | 複雑な正規表現は表示されません | |
hsla | 弦 | 複雑な正規表現は表示されません | |
Eメール | 弦 | 複雑な正規表現は表示されません | `検証:"電子メール"` |
URL | 弦 | URL ルール | `検証:"url"` |
ウリ | 弦 | ウリルール | `検証:"uri"` |
Base64 | 弦 | "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za- z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" | `検証:"base64"` |
含まれています | 弦 | 含む | `validate:"contains=目的"` |
何かを含む | 弦 | どれかが含まれています | `validate:"containsany=!@#$"` |
除外します | 弦 | 含まれていない | `validate:"excludes=text"` |
すべてを除く | 弦 | 何も含まれていません | `validate:"excludesall=!@#$"` |
ルーンを除く | 弦 | ルーンタイプは含まれていません | `validate:"excludesrune=☻"` |
ISBN | 弦 | 2枚のisbn | `検証:"isbn"` |
ISBN10 | 弦 | "^(?:[0-9]{9}X|[0-9]{10})$" | `検証:"isbn10"` |
ISBN13 | 弦 | ^(?:(?:97(?:8|9))[0-9]{10})$" | `検証:"isbn13"` |
uuid | 弦 | "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" | `validate:"uuid"` |
uuid3 | 字符串 | "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" | `validate:"uuid3"` |
uuid4 | 字符串 | "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" | `validate:"uuid4"` |
uuid5 | 字符串 | "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" | `validate:"uuid5"` |
ascii | 字符串 | "^[\x00-\x7F]*$" | `validate:"ascii"` |
printascii | 字符串 | ^[\x20-\x7E]*$" | `validate:"printascii"` |
multibyte | 字符串 | "[^\x00-\x7F]" | `validate:"multibyte"` |
datauri | 字符串 | `^data:((?:\w+\/(?:([^;]|;[^;]).)+)?)` | `validate:"datauri"` |
latitude | 字符串 | "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" | `validate:"latitude"` |
longitude | 字符串 | "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" | `validate:"longitude"` |
ssn | 字符串 | ^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$` | `validate:"ssn"` |
ip | 字符串 | ip规则 | `validate:"ip"` |
ipv4 | 字符串 | ipv4规则 | `validate:"ipv4"` |
ipv6 | 字符串 | ipv6规则 | `validate:"ipv6"` |
cidr | 字符串 | ip规则 | `validate:"cidr"` |
cidrv4 | 字符串 | ipv4规则 | `validate:"cidrv4"` |
cidrv6 | 字符串 | ipv6规则 | `validate:"cidrv6"` |
tcp_addr | 字符串 | 对应规则按需验证 | `validate:"tcp_addr"` |
tcp4_addr | 字符串 | 对应规则按需验证 | `validate:"tcp4_addr"` |
tcp6_addr | 字符串 | 对应规则按需验证 | `validate:"tcp6_addr"` |
udp_addr | 字符串 | 对应规则按需验证 | `validate:"udp_addr"` |
udp4_addr | 字符串 | 对应规则按需验证 | `validate:"udp4_addr"` |
udp6_addr | 字符串 | 对应规则按需验证 | `validate:"udp6_addr"` |
ip_addr | 字符串 | 对应规则按需验证 | `validate:"ip_addr"` |
ip4_addr | 字符串 | 对应规则按需验证 | `validate:"ip4_addr"` |
ip6_addr | 字符串 | 对应规则按需验证 | `validate:"ip6_addr"` |
unix_addr | 字符串 | 对应规则按需验证 | `validate:"unix_addr"` |
mac | 字符串 | 对应规则按需验证 | `validate:"mac"` |
iscolor | 字符串 | 颜色校验所有颜色规则 | `validate:"iscolor"` |
oneof | OneOfString | 对应规则按需验证 | `validate:"oneof=red green"` |
oneof | OneOfInt | 对应规则按需验证 | `validate:"oneof=5 63"` |
unique | UniqueSlice | 对应规则按需验证 | `validate:"unique"` |
unique | UniqueArray | 对应规则按需验证 | `validate:"unique"` |
unique | UniqueMap | 对应规则按需验证 | `validate:"unique"` |
json | JSONString | 对应规则按需验证 | `validate:"json"` |
lowercase | LowercaseString | 对应规则按需验证 | `validate:"lowercase"` |
uppercase | UppercaseString | 对应规则按需验证 | `validate:"uppercase"` |
datetime | Datetime | 对应规则按需验证 | `validate:"datetime=2006-01-02"` |
----- 接下来的工作 重写swagger-models的生成过程, 目前来看swagger-go 的生成过程对于models的处理只针对definetion的处理。加上go语言的特性使allof 以及 discriminator: "type" 是冲突的,所以我将重写这一部分让models 关注models
------ 整体入参无论是 path ,query , header , form 中可获取参数 跟随者models一起 定义在 具体的operation的Handle入参之中。 以完成校验。