酷 Go 推薦 Validator 網路請求資料驗證包

Aklman發表於2021-04-06

背景介紹


validator 是提供了比較強大的,可支援定製化的資料驗證規則的包,它提供了很方便的方法及驗證規則來驗證傳入的 HTTP 請求資料,可以一次定義多次使用,非常優雅地解決了資料驗證雜亂問題,有利於拆解業務程式碼中的資料驗證相關程式碼,這樣整個控制器中的程式碼看起來比較整潔便於閱讀。

快速使用

  1. 執行 go get github.com/go-playground/validator/v10 以安裝包。
  2. 把包匯入到需要使用的專案檔案中。
  3. 構造驗證規則。
package main

import (
    "fmt"
    "github.com/go-playground/validator/v10"
)

// 使用者資訊
type User struct {
    Name      string     `validate:"required"`
    Age       uint8      `validate:"gte=0,lte=130"`
    Email     string     `validate:"required,email"`
    Phone     int64      `validate:"required,number"`
    Addresses []*Address `validate:"required,dive,required"`
}

// 使用者地址資訊
type Address struct {
    Street string `validate:"required"`
    City   string `validate:"required"`
    Phone  string `validate:"required"`
}

// 用 Validate 的單個例項來快取結構體資訊
var validate *validator.Validate


func main() {
    //建立一個示例
    validate = validator.New()

    address := &Address{
        Street: "Lujiazui No.21 ",
        City:   "Shanghai",
        Phone:  "021-7777777",
    }

    user := &User{
        Name:      "Aklman",
        Age:       135,
        Email:     "aklman888@gmail.com",
        Phone:     17702177888,
        Addresses: []*Address{address},
    }
    //驗證結構體
    validateStruct(user)
    //單一驗證變數
    validateVariable()
}

//複雜結構資料的驗證
func validateStruct(user *User) {
    err := validate.Struct(user)
    if err != nil {
        if _, ok := err.(*validator.InvalidValidationError); ok {
            fmt.Println(err)
            return
        }

        for _, err := range err.(validator.ValidationErrors) {

            fmt.Println(err.Namespace())
            fmt.Println(err.Field())
            fmt.Println(err.StructNamespace())
            fmt.Println(err.StructField())
            fmt.Println(err.Tag())
            fmt.Println(err.ActualTag())
            fmt.Println(err.Kind())
            fmt.Println(err.Type())
            fmt.Println(err.Value())
            fmt.Println(err.Param())
            fmt.Println()
        }
        return
    }

    // 執行下一步操作
}

//單一結構體的資料驗證
func validateVariable() {
    myEmail := "aklman888@gmail.com"

    errs := validate.Var(myEmail, "required,email")

    if errs != nil {
        fmt.Println(errs)
        return
    }
}

基本資料驗證規則符號

0. 比較運算子

運算子 運算描述
eq 等於
gt 大於
gte 大於等於
lt 小於
lte 小於等於
ne 不等於

1. 欄位驗證運算

運算子 運算描述
eqcsfield 跨不同結構體欄位相等
eqfield 同一結構體欄位相等
fieldcontains 包含欄位
fieldexcludes 未包含欄位
gtcsfield 跨不同結構體欄位大於
gtecsfield 跨不同結構體欄位大於等於
gtefield 同一結構體欄位大於等於
gtfield 同一結構體欄位相等
ltcsfield 跨不同結構體欄位小於
ltecsfield 跨不同結構體欄位小於等於
ltefield 同一個結構體欄位小於等於
ltfield 同一個結構體欄位小於
necsfield 跨不同結構體欄位不想等
nefield 同一個結構體欄位不想等

2. 網路欄位驗證運算

運算子 運算描述
cidr 有效 CIDR
cidrv4 有效 CIDRv4
cidrv6 有效 CIDRv6
datauri 是否有效 URL
fqdn 有效完全合格的域名 (FQDN)
hostname 是否站點名稱 RFC 952
hostname_port 是否站點埠
ip 是否包含有效 IP
ip4_addr 是否有效 IPv4
ip6_addr 是否有效 IPv6
ip_addr 是否有效 IP
ipv4 是否有效 IPv4
ipv6 是否有效 IPv6
mac 是否媒體有效控制有效 MAC 地址
tcp4_addr 是否有效 TCPv4 傳輸控制協議地址
tcp6_addr 是否有效 TCPv6 傳輸控制協議地址
tcp_addr 是否有效 TCP 傳輸控制協議地址
udp4_addr 是否有效 UDPv4 使用者資料包協議地
udp6_addr 是否有效 UDPv6 使用者資料包協議地
udp_addr 是否有效 UDPv 使用者資料包協議地
unix_addr Unix 域套接字端點地址
uri 是否包含有效的 URI
url 是否包含有效的 URL

3. 字串驗證運算

運算子 運算描述
alpha 是否全部由字母組成的
alphanum 是否全部由數字組成的
alphanumunicode 是否全部由 unicode 字母數字組成
alphaunicode 是否全部由 unicode 字母組成
ascii ASCII
contains 是否包含全部
endswith 尾部是否以此字元結束
lowercase 是否全小寫字元組成
multibyte 是否多位元組字元
number 是否數字
numeric 是否包含基本的數值
printascii 是否可列印的 ASCII
startswith 開頭是否以此字元開始
uppercase 是否全大寫字元組成

4. 資料格式驗證運算

運算子 運算描述
base64 是否 Base64
base64url 是否 Base64UR
btc_addr 是否 Bitcoin 地址
btc_addr_bech32 是否 Bitcoin Bech32 地址
datetime 是否有效 Datetime
email 是否有效 E-mail
html 是否有效 HTML 標籤
json 是否有效 JSON
rgb 是否有效 RGB
rgba 是否有效 RGBA
uuid 是否有效通用唯一識別符號

5. 其他驗證運算

運算子 運算描述
dir 是否有效目錄
file 是否有效檔案目錄
isdefault 是預設值
len 指定長度
max 最大值
min 最小值
required 必須傳入
unique 唯一的

總結


validator 好用之處是一次寫就可以多次使用無需寫繁瑣程式碼來進行資料驗證,通常驗證規則單獨拿出來放在一個包中,需要時直接呼叫,不用在業務邏輯程式碼中驗證。

點選瞭解更多

參考資料

  1. GitHub README
  2. pkg.go.dev validator
更多原創文章乾貨分享,請關注公眾號
  • 酷 Go 推薦 Validator  網路請求資料驗證包
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章