Gin要求パラメータチェック


ginパラメータチェックはvalidatorライブラリを使用しているので、本稿の内容はvalidatorを使用してパラメータチェックを行う場所にも適用されます.
検証ルール
完全な検証ルールは参照できますhttps://godoc.org/github.com/go-playground/validatorを選択します.
  • 数値制限
    注意:制限の間に衝突がある場合、eq=10,ne=10のように、前後の順序に基づいて、後の定義は前の定義を上書きし、後の定義を基準とします.検査内容はeq=10,ne=10で、ne=10しか発効しません.衝突があれば、すべての検査規則はこの法則に合致します.
  • 制限範囲
    max=10 #     10,     10
    min=10 #     10,     10
    gt=10  #    10
    gte=10 #     10
    lt=10  #   10
    lte=10 #     10
    
  • 制限値
    eq=10 #   10
    ne=10 #    10
    oneof=1 2 3 #     1、2   3
    len=3 #      3  
    
  • 文字列長制限{{
  • :もじれつせいげん}}
  • 制限長さ範囲
    max=10 #      10
    min=10 #      10
    gt=10  #     10
    lt=10  #     10
    gte=10 #       10
    let=10 #       10
    
  • 制限値内容
    eq=aaa #   aaa
    ne=aaa #     aaa
    oneof=a b c #   ,   a、b   c
    len=3 #      3
    
  • 存在性検査
    注:ここで特に注意が必要なのは、ここに存在するかどうかは0値と非0値で判断され、フィールドに対応する0値が渡された場合、存在しないとみなされます
  • 必須
    required #   
    
  • オプション
    omitempty,xxx=xxx #   ,    ,         xxx=xxx,     , xxx=xxx   ,    omitempty        ,             ,  gte=-1,omitempty,len=3, gte=-1      , len=3      0   。
    
  • 関連検査
    required_with=AAA #  AAA   ,        
    required_with_all=AAA BBB CCC  #  AAA BBB CCC     ,       
    required_without=AAA #  AAA    ,       
    required_without_all=AAA BBB #  AAA BBB      ,       
    
  • 構造体フィールド間チェック
  • 1階層内部検査
    eqfield=AAA #    AAA   
    nefield=AAA #    AAA    
    gtfield=AAA #     AAA  
    gtefield=AAA #       AAA  
    ltfield=AAA #     AAA  
    ltefield=AAA #     AAA    
    
  • 複数階層間チェック
    eqcsfield=AAA.B  #   AAA  B  
    necsfield=AAA.B  #    AAA  B  
    gtcsfield=AAA.B  #   AAA  B  
    gtecsfield=AAA.B #     AAA  B  
    ltcsfield=AAA.B  #   AAA  B  
    ltecsfield=AAA.B #     AAA  B  
    
    注意:ここで注意したいのは、複数の構造体間の検証は、フィールド間に階層的なつながりが存在し、上位レベルと下位レベルの関連付けのみで、次のように逆にすることはできません.
    type Timeout struct {
    	Connect int `json:"connect" validate:"required"`
    	Read    int `json:"read" validate:"required"`
    	Send    int `json:"send" validate:"required"`
    }
    
    type MyStruct struct {
    	Name    string   `json:"name" validate:"required"`
    	Out     int      `json:"out" validate:"eqcsfield=Timeout.Connect"` //    Timeout       Timeout    ,  Timeout          
    	Timeout Timeout  `json:"timeout"`
    }
    

  • dive配列検査diveとは潜水を意味し、潜水つまり水下に深く入り込むことを意味し、diveはここでは差が少なく、より深く入り込むことを意味し、現在のフィールドタイプが[]stringであるように、1層深く入り込むと、 (array)から (array )になり、検査に対応し、dive前は全体検査である.dive後は全体の要素チェックです.例:
  • 一般配列
    Domains []string `binding:"gt=0,dive,required,min=1,max=100"`
    
    検査内容:[]stringの長さは0より大きくなければならず、配列中の要素stringの長さは1-100の間で
  • でなければならない.
  • 構造体配列検査
       Cors         []AStruct    `binding:"dive"`
    
    ここではdive前後に関連検査規則は定義されていないが、AStructで定義された検査規則を有効にするにはdiveが必要であり、そうでなければAStructで定義された規則は
  • を有効にしない.
  • diveのMapチェックdiveに対する意味は、ここでは配列に類似しており、 -> の規則は変わらないが、mapの特殊性はvalue値だけでなくkey値もあることであり、ここではvalueをチェックするか、検証keyをチェックするかを区別する方法が必要である.ここではkeysとendkeysを使用してkey値のチェック範囲をマークし、keysからendkeys終了まで
    ReqHeaders      map[string]string         `binding:"dive,keys,min=1,max=100,endkeys,required,min=1,max=100"`
    
    チェック内容:全体をチェックせず、制限key値の長さは1-100の間でなければならず、value値の長さも1-100の間で
  • でなければならない.
  • structonly構造体が検証ルールを定義しているが、これらの検証ルールが有効になる必要がない場合、structonlyタグを使用することができ、このタグが存在する構造体内部の検証ルールは再有効になりません.以下のように、
    type Timeout struct {
    	Connect int `json:"connect" binding:"required"`
    	Read    int `json:"read" binding:"required"`
    	Send    int `json:"send" binding:"required"`
    }
    
    type MyStruct struct {
    	Name    string   `json:"name" binding:"required"`
    	Timeout Timeout `json:"timeout" binding:"structonly"` 
    }
    
    構造体Timeoutの各フィールドは検証内容を定義するが、MyStructTimeoutフィールドにstructonlyタグを使用すると、Timeoutで定義された検証内容は
  • から有効にならない.
  • nostructlevel nostructlevelはstructonlyに似ています.唯一の違いは、ルールを無視する効果が有効になるには、requiredまたはomitempty
    type Timeout struct {
    	Connect int `json:"connect" binding:"required,gte=1,lte=1000"`
    	Read    int `json:"read" binding:"gte=1,lte=1000"`
    	Send    int `json:"send" binding:"gte=1,lte=1000"`
    }
    
    type MyStruct struct {
    	Name    string   `form:"name" json:"name" binding:"required"`
    	UseMeta bool     `json:"use_meta"`
    	Timeout Timeout `json:"timeout" binding:"required,nostructlevel"`
    }
    
  • を使用する必要があります.
  • 検査規則
    - #         ,        ,              
    
  • を無視する
  • マルチチェックルール 演算
    | #               ,   |                
    
  • ginでの使用方法
    1.検査パラメータ定義
    検証パラメータは構造体に定義されているので、まずデータを受け入れる構造体を定義し、各属性の検証パラメータを定義する必要があります.
    type Timeout struct {
    	Connect int `binding:"omitempty,gte=1,lte=75"`
    	Read    int `binding:"omitempty,gte=1,lte=1000"`
    	Send    int `binding:"omitempty,gte=1,lte=1000"`
    }
    
    type MyTestStruct struct {
    	Domains []string `binding:"gt=0,dive,required,min=1,max=100"`
    	Name    string   `binding:"required"`
    	UseTimeout bool
    	Timeout Timeout `binding:"required_with=UseTimeout"`
    }
    

    構造体フィールドbinding tagの内容がチェックパラメータである.
    2.データバインド
    ginでは、構造体との自動データのバインドを実現するために一般的なShouldBindWith/ShouldBindUri方法が提供され、以下のタイプのデータが提供されています.
    データ型
    Tag
    Context-Type
    データソース
    使用例
    JSON
    json
    application/json
    Body
    ShouldBindWith(&data, binding.Query)
    XML
    xml
    application/xml、text/xml
    Body
    ShouldBindWith(&data, binding.XML)
    Form
    form
    application/x-www-form-urlencoded
    Body
    c.ShouldBindWith(&data, binding.Form)
    Query
    form
    url query
    ShouldBindWith(&data, binding.Query)
    FormPost
    form
    application/x-www-form-urlencoded
    Body
    ShouldBindWith(&data, binding.FormPost)
    FormMultipart
    form
    multipart/form-data
    Body
    ShouldBindWith(&data, binding.FormMultipart)
    ProtoBuf
    application/x-protobuf
    Body
    ShouldBindWith(&data, binding.ProtoBuf)
    MsgPack
    application/x-msgpack、application/msgpack
    Body
    ShouldBindWith(&data, binding.MsgPack)
    YAML
    application/x-yaml
    Body
    ShouldBindWith(&data, binding.YAML)
    Uri
    uri
    uri
    ShouldBindUri(&data)
    Header
    header
    Header
    ShouldBindWith(&forwardRule, binding.Header)
    説明:
  • データ型:伝送されるデータ型
  • を指す.
  • Tag:構造体定義のTagは、Formタイプデータのidが構造体のIDフィールドに対応するように、データフィールドと構造体フィールドとの対応関係を明らかにしている.
  • Context-Type:HTTPのHeaderフィールドの1つで、Bodyのデータ型を表します.gin.ContextBindメソッドは、Content-Typeに従って、対応するタイプの
    type xxxx struct {
    	...
    	ID int64 `form:"id"`
    	...
    }
    
    にデータを自動的にバインドします.
    注意:MustBindWithShouldBindWithの違いは、MustBindWithがエラー情報を自動的に返すことです.統一されたエラー戻りフォーマットがある場合は、MustBindWithが戻りフォーマットの統一性を破壊する可能性があります.
  • データソース:どこからデータを取得するか、BodyはHTTP Bodyからデータを取得すること、url queryはURLのqueyパラメータからデータを取得すること、urlはurlからパラメータを取得すること、例えば/api/v1/xxx/:id、idパラメータはurlから取得する
  • である.
  • 使用例:使用するルーチン
  • 3.検査結果取得ShouldBindWithはerror情報を返します.error情報が空でない場合、エラーが発生したことを示し、エラー情報がerrorに含まれます.errorが空の場合、検証が通過したことを示します.例は次のとおりです.
    func (c *Context) Bind(obj interface{}) error {
    	b := binding.Default(c.Request.Method, c.ContentType()) //       
    	return c.MustBindWith(obj, b) //     
    }