詳解Go語言中Validator庫(kù)的使用方法和用途
1. 引言
github.com/go-playground/validator 是一個(gè) Go 語言的庫(kù),用于對(duì)結(jié)構(gòu)體字段進(jìn)行驗(yàn)證。它提供了一種簡(jiǎn)單而靈活的方式來定義驗(yàn)證規(guī)則,并在驗(yàn)證過程中檢查結(jié)構(gòu)體字段是否滿足這些規(guī)則。這個(gè)庫(kù)可以用于驗(yàn)證各種數(shù)據(jù),包括從用戶輸入到 API 請(qǐng)求中的數(shù)據(jù),以確保數(shù)據(jù)的完整性和有效性。
在這篇文章中,我們將從一個(gè)簡(jiǎn)單的問題出發(fā),帶你了解 Validator 庫(kù)的用途,也會(huì)介紹Validator 的基本使用,同時(shí)也會(huì)介紹Validator 能夠給我們帶來的優(yōu)點(diǎn)。
2. 問題引入
在平常開發(fā)過程中,不管是Web應(yīng)用程序來接收頁面請(qǐng)求,還是創(chuàng)建一個(gè)服務(wù)來接收其他服務(wù)的請(qǐng)求,不可避免的,我們都需要檢查請(qǐng)求參數(shù)是否合法,是否有效。
假設(shè)我們開發(fā)一個(gè)用戶注冊(cè)功能的 Web 應(yīng)用程序。用戶在注冊(cè)頁面上提供了以下信息:用戶名、電子郵件地址、密碼和確認(rèn)密碼。那么我們必須編寫下述代碼,保證用戶輸入信息合法性,如下:
type User struct {
Username string
Email string
}
func (u *User) checkUserIsInvalid() error {
// 檢查用戶名長(zhǎng)度是否合法
if len(user.Username) < 3 || len(user.Username) > 20 {
return errors.New("Invalid username length")
}
// 檢查電子郵件地址是否合法
if !isValidEmail(user.Email) {
return errors.New("Invalid email address")
}
return nil
}
func registerUser(user User) error {
// 檢查輸入是否合法
err := user.checkUserIsInvalid()
if err != nil {
return errors.New("Invalid Input")
}
// 用戶注冊(cè)邏輯...
return nil
}這里的實(shí)現(xiàn)并沒有太大的問題。但是如果程序中有20個(gè)地方,都檢查了用戶名長(zhǎng)度是否合法,如果這個(gè)驗(yàn)證邏輯更復(fù)雜一點(diǎn),那就不太合理了,這里的一個(gè)做法是將驗(yàn)證邏輯抽取為一個(gè)函數(shù),示例如下:
func checkUserNameIsValid(username string) bool{
if len(username) < 3 || len(username) > 20 {
return false
}
return true
}然后用到這段邏輯的,直接調(diào)用該函數(shù)即可,不需要再重復(fù)實(shí)現(xiàn),這個(gè)也能夠解決一部分場(chǎng)景的問題。但是假想一下,如果我們的驗(yàn)證邏輯不像上面那么簡(jiǎn)單,而是涉及到多個(gè)字段的組合驗(yàn)證,類型轉(zhuǎn)換,嵌套結(jié)構(gòu)體的場(chǎng)景,這個(gè)時(shí)候我們的驗(yàn)證邏輯會(huì)非常復(fù)雜。
比如我們需要實(shí)現(xiàn)一個(gè)嵌套結(jié)構(gòu)體的校驗(yàn)邏輯,此時(shí)我們需要遍歷每一個(gè)字段,可能會(huì)有非常深的if...else代碼,亦或者比較深層次的函數(shù)調(diào)用,這個(gè)復(fù)雜邏輯不管是實(shí)現(xiàn)還是后續(xù)的閱讀,都會(huì)花費(fèi)我們大量的精力。
回歸到我們的訴求,其實(shí)我們并不是很關(guān)心嵌套了多少層結(jié)構(gòu)體,我們更關(guān)注的是針對(duì)某一個(gè) 字段/值,其值是否滿足我們的預(yù)期。那有沒有辦法,做到我們實(shí)現(xiàn)一個(gè)驗(yàn)證邏輯,通過某種手段作用到目標(biāo)字段,而不需要去關(guān)注具體的數(shù)據(jù)結(jié)構(gòu),這樣子既能做到驗(yàn)證邏輯的復(fù)用,同時(shí)也避免了對(duì)復(fù)雜數(shù)據(jù)結(jié)構(gòu)的解析,從而簡(jiǎn)化我們的驗(yàn)證邏輯。
其實(shí)還真有,當(dāng)前存在大量的驗(yàn)證庫(kù),能夠幫助我們實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證。接下來我們就來了解下Go語言中的Validator庫(kù),其能夠讓我們專注于驗(yàn)證邏輯的編寫,而不需要考慮邏輯的復(fù)用以及復(fù)雜數(shù)據(jù)結(jié)構(gòu)的處理等許多問題,同時(shí)在某種程度上也提高了代碼的可讀性。
3. Validator 的基本使用
Validator 是基于標(biāo)簽來實(shí)現(xiàn)的,我們只需要在結(jié)構(gòu)體的字段上使用 validate 標(biāo)簽,然后設(shè)置標(biāo)簽值,每一個(gè)標(biāo)簽值代表一個(gè)驗(yàn)證規(guī)則。這些標(biāo)簽值將告訴 validator 結(jié)構(gòu)體的字段應(yīng)該滿足哪些條件,然后通過調(diào)用Validator 提供的 API ,便能夠?qū)崿F(xiàn)數(shù)據(jù)的校驗(yàn)。
下面我們通過一個(gè)簡(jiǎn)單的例子來進(jìn)行說明,幫助我們快速入門Validator 庫(kù)的使用:
type User struct {
FirstName string `validate:"required"`
LastName string `validate:"required"`
Age uint8 `validate:"gte=20,lte=60"`
Email string `validate:"required,email"`
}
func main() {
validate = validator.New()
user := &User{
FirstName: "Badger",
LastName: "Smith",
Age: 18,
Email: "Badger.Smith@gmail.com",
}
// returns nil or ValidationErrors ( []FieldError )
err := validate.Struct(user)
if err != nil {
fmt.Println(err)
}
}上面例子中,我們定義了一個(gè) User 結(jié)構(gòu)體,包含了不同類型的字段,每個(gè)字段都通過validate 標(biāo)簽定義一些驗(yàn)證規(guī)則。
其中FirstName 和 LastName 都設(shè)置了 required 規(guī)則,Age 設(shè)置了gte=0 和 lte=130 規(guī)則,Email 則設(shè)置了required 和 email 兩個(gè)規(guī)則。其中required,gte,lte 和 email 規(guī)則是 Validator 庫(kù)自帶的校驗(yàn)規(guī)則,可以直接設(shè)置。
在結(jié)構(gòu)體設(shè)置好驗(yàn)證規(guī)則后,在main 函數(shù)中通過New 方法創(chuàng)建一個(gè) Validate 實(shí)例,然后通過調(diào)用Struct 方法,便會(huì)自動(dòng)根據(jù)結(jié)構(gòu)體標(biāo)簽設(shè)置的規(guī)則對(duì)對(duì)象的值進(jìn)行驗(yàn)證。如果驗(yàn)證通過,將返回nil,否則會(huì)返回一個(gè)ValidationErrors類型的錯(cuò)誤對(duì)象,其中包含驗(yàn)證失敗的詳細(xì)信息。
比如上面Age 字段不滿足條件,此時(shí)user 對(duì)象將不能通過校驗(yàn),會(huì)返回對(duì)應(yīng)的錯(cuò)誤信息,如下:
Key: 'User.Age' Error:Field validation for 'Age' failed on the 'gte' tag
4. Validator優(yōu)點(diǎn)
如果我們使用 Validator 庫(kù),邏輯就可以抽取出來為一個(gè)公共的驗(yàn)證庫(kù),然后每一個(gè)驗(yàn)證邏輯對(duì)應(yīng)一個(gè)驗(yàn)證規(guī)則名,這個(gè)Validator 庫(kù)有支持,后續(xù)會(huì)講述到。
然后在結(jié)構(gòu)體中,使用validate 標(biāo)簽指定需要的驗(yàn)證規(guī)則,這樣子我們就不需要待驗(yàn)證數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),也復(fù)用了驗(yàn)證規(guī)則,同時(shí)將驗(yàn)證規(guī)則與字段綁定到一起,也提高了代碼的可讀性。
通過使用Validator 庫(kù),我們能夠回歸到核心關(guān)注的內(nèi)容,驗(yàn)證傳入數(shù)據(jù)的合法性, 而不是去解析數(shù)據(jù)結(jié)構(gòu),代碼復(fù)用等一系列復(fù)雜的事情,把這些復(fù)雜的事情交給 Validator 幫我們做。
5. 總結(jié)
本文介紹了 Go 語言中的 github.com/go-playground/validator 庫(kù),該庫(kù)用于對(duì)結(jié)構(gòu)體字段進(jìn)行驗(yàn)證。文章從一個(gè)簡(jiǎn)單的問題出發(fā),引入了Validator 庫(kù)的使用。
之后介紹了 Validator 庫(kù)的基本使用,包括如何創(chuàng)建驗(yàn)證實(shí)例、執(zhí)行驗(yàn)證以及處理驗(yàn)證錯(cuò)誤。通過示例代碼,演示了如何使用標(biāo)簽來設(shè)置驗(yàn)證規(guī)則,以及如何通過 Validator 庫(kù)簡(jiǎn)化數(shù)據(jù)驗(yàn)證過程,提高代碼的可讀性和可維護(hù)性。
總的來說,在比較復(fù)雜的場(chǎng)景,通過使用Validator庫(kù),我們可以專注于驗(yàn)證邏輯的編寫,而不必?fù)?dān)心數(shù)據(jù)結(jié)構(gòu)的解析和重復(fù)的驗(yàn)證代碼,能夠很好得提高代碼的可讀性和可維護(hù)性。
以上就是詳解Go語言中Validator庫(kù)的使用方法和用途的詳細(xì)內(nèi)容,更多關(guān)于Go Validator庫(kù)使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go進(jìn)階之長(zhǎng)參數(shù)函數(shù)的實(shí)現(xiàn)
本文主要介紹了Go語言中變長(zhǎng)參數(shù)函數(shù)的使用方法和應(yīng)用場(chǎng)景,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-06-06
Go語言處理超大字符串型整數(shù)加減經(jīng)典面試詳解
這篇文章主要為大家介紹了Go語言處理超大字符串型整數(shù)加減經(jīng)典面試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
go自動(dòng)下載所有的依賴包go module使用詳解
這篇文章主要介紹了go自動(dòng)下載所有的依賴包go module使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Golang利用WebSocket實(shí)現(xiàn)實(shí)時(shí)推送功能
WebSocket 是一個(gè)實(shí)時(shí)雙向通信的協(xié)議,底層用 TCP,借用 HTTP 建立連接,專門用來做實(shí)時(shí)功能,下面小編就和大家詳細(xì)介紹一下Golang如何利用WebSocket實(shí)現(xiàn)實(shí)時(shí)推送功能吧2026-03-03

