Model binding dan validasi
Untuk melakukan binding body permintaan ke dalam sebuah tipe, gunakan model binding. Kami saat ini mendukung binding JSON, XML, YAML dan nilai formulir standar (foo=bar&boo=baz).
Gin menggunakan go-playground/validator/v10 untuk validasi. Lihat dokumentasi lengkap penggunaan tag di sini.
Perhatikan bahwa Anda perlu mengatur tag binding yang sesuai pada semua field yang ingin Anda bind. Contohnya, saat binding JSON, atur json:"fieldname"
.
Selain itu, Gin menyediakan dua kumpulan metode untuk binding:
- Tipe - Wajib bind
- Metode -
Bind
,BindJSON
,BindXML
,BindQuery
,BindYAML
- Perilaku - Metode-metode ini menggunakan
MustBindWith
di balik layar. Jika terjadi galat binding, permintaan akan dihentikan denganc.AbortWithError(400, err).SetType(ErrorTypeBind)
. Ini mengatur kode status respons menjadi 400 dan headerContent-Type
diatur ketext/plain; charset=utf-8
. Perhatikan bahwa jika Anda mencoba mengatur kode respons setelah ini, akan menghasilkan peringatan[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422
. Jika Anda ingin memiliki kontrol yang lebih besar atas perilakunya, pertimbangkan untuk menggunakan metode yang setara denganShouldBind
.
- Metode -
- Tipe - Seharusnya bind
- Metode -
ShouldBind
,ShouldBindJSON
,ShouldBindXML
,ShouldBindQuery
,ShouldBindYAML
- Perilaku - Metode-metode ini menggunakan
ShouldBindWith
di balik layar. Jika terjadi galat binding, error dikembalikan dan merupakan tanggung jawab developer untuk menangani permintaan dan error dengan tepat.
- Metode -
Saat menggunakan metode Bind, Gin mencoba menginferensi binder berdasarkan header Content-Type. Jika Anda yakin apa yang Anda bind, Anda dapat menggunakan MustBindWith
atau ShouldBindWith
.
Anda juga dapat menentukan bahwa field tertentu diperlukan. Jika sebuah field ditandai dengan binding:"required"
dan memiliki nilai kosong saat binding, sebuah error akan dikembalikan.
// Binding dari JSONtype Login struct { User string `form:"user" json:"user" xml:"user" binding:"required"` Password string `form:"password" json:"password" xml:"password" binding:"required"`}
func main() { router := gin.Default()
// Contoh binding JSON ({"user": "manu", "password": "123"}) router.POST("/loginJSON", func(c *gin.Context) { var json Login if err := c.ShouldBindJSON(&json); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return }
if json.User != "manu" || json.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return }
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) })
// Contoh binding XML ( // <?xml version="1.0" encoding="UTF-8"?> // <root> // <user>manu</user> // <password>123</password> // </root>) router.POST("/loginXML", func(c *gin.Context) { var xml Login if err := c.ShouldBindXML(&xml); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return }
if xml.User != "manu" || xml.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return }
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) })
// Contoh binding formulir HTML (user=manu&password=123) router.POST("/loginForm", func(c *gin.Context) { var form Login // Ini akan menginferensi binder apa yang akan digunakan berdasarkan header content-type. if err := c.ShouldBind(&form); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return }
if form.User != "manu" || form.Password != "123" { c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"}) return }
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"}) })
// Jalankan server pada 0.0.0.0:8080 router.Run(":8080")}
Contoh permintaan
$ curl -v -X POST \ http://localhost:8080/loginJSON \ -H 'content-type: application/json' \ -d '{ "user": "manu" }'> POST /loginJSON HTTP/1.1> Host: localhost:8080> User-Agent: curl/7.51.0> Accept: */*> content-type: application/json> Content-Length: 18>* upload completely sent off: 18 out of 18 bytes< HTTP/1.1 400 Bad Request< Content-Type: application/json; charset=utf-8< Date: Fri, 04 Aug 2017 03:51:31 GMT< Content-Length: 100<{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
Lewati validasi
Saat menjalankan contoh di atas menggunakan perintah curl
, akan mengembalikan error. Karena contoh tersebut menggunakan binding:"required"
untuk Password
. Jika menggunakan binding:"-"
untuk Password
, maka tidak akan mengembalikan error saat menjalankan contoh di atas lagi.