C.5. HTTP Request Payload Validation (Validator v9, Echo)
Pada chapter ini kita akan belajar cara validasi payload request di sisi back end. Library yang kita gunakan adalah github.com/go-playground/validator/v10, library ini sangat berguna untuk keperluan validasi data.
C.5.1. Payload Validation
Penggunaan validator cukup mudah, di struct penampung payload, tambahkan tag baru pada masing-masing property dengan skema validate:"<rules>"
.
Langsung saja kita praktekan, buat folder project baru dengan isi file main.go
, lalu tulis kode berikut ke dalamnya.
package main
import (
"github.com/labstack/echo"
"github.com/go-playground/validator/v10"
"net/http"
)
type User struct {
Name string `json:"name" validate:"required"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"gte=0,lte=80"`
}
Struct User
memiliki 3 field, berisikan aturan/rule validasi, yang berbeda satu sama lain (bisa dilihat pada tag validate
). Kita bahas validasi per-field agar lebih mudah untuk dipahami.
- Field
Name
, tidak boleh kosong. - Field
Email
, tidak boleh kosong, dan isinya harus dalam format email. - Field
Age
, tidak harus di-isi; namun jika ada isinya, maka harus berupa numerik dalam kisaran angka 0 hingga 80.
Kurang lebih berikut adalah penjelasan singkat mengenai beberapa rule yang kita gunakan di atas.
- Rule
required
, menandakan bahwa field harus di isi. - Rule
email
, menandakan bahwa value pada field harus dalam bentuk email. - Rule
gte=n
, artinya isi harus numerik dan harus di atasn
atau sama dengann
. - Rule
lte=n
, berarti isi juga harus numerik, dengan nilai di bawahn
atau sama dengann
.
Jika sebuah field membutuhkan dua atau lebih rule, maka tulis seluruhnya dengan delimiter tanda koma (,
).
OK, selanjutnya buat struct baru CustomValidator
dengan isi sebuah property bertipe *validator.Validate
dan satu buah method ber-skema Validate(interface{})error
. Objek cetakan struct ini akan kita gunakan sebagai pengganti default validator milik echo.
type CustomValidator struct {
validator *validator.Validate
}
func (cv *CustomValidator) Validate(i interface{}) error {
return cv.validator.Struct(i)
}
func main() {
e := echo.New()
e.Validator = &CustomValidator{validator: validator.New()}
// routes here
e.Logger.Fatal(e.Start(":9000"))
}
Method .Struct()
milik *validator.Validate
, digunakan untuk mem-validasi data objek dari struct.
Library validator menyediakan banyak sekali cakupan data yang bisa divalidasi, tidak hanya struct, lebih jelasnya silakan lihat di laman github https://github.com/go-playground/validator.
Siapkan sebuah endpoint untuk keperluan testing. Dalam endpoint ini method Validate
milik CustomValidator
dipanggil.
e.POST("/users", func(c echo.Context) error {
u := new(User)
if err := c.Bind(u); err != nil {
return err
}
if err := c.Validate(u); err != nil {
return err
}
return c.JSON(http.StatusOK, true)
})
OK, jalankan aplikasi, lakukan testing.
Bisa dilihat pada gambar di atas, ada beberapa request yang mengembalikan error.
- Request pertama adalah valid.
- Request ke-2 error karena value dari field
email
tidak valid. Harusnya berisi value dalam format email. - Request ke-3 error karena value field
age
lebih dari 80. Value seharusnya numerik kisaran 0 hingga 80. - Sedangkan request ke-4 sukses meskipun
age
adalahnull
, hal ini karena rule untuk field tersebut tidak adarequired
.
Field
Age
tidak harus di-isi; namun jika ada isinya, maka harus berupa numerik dalam kisaran angka 0 hingga 80.
Dari testing di atas bisa kita simpulkan bahwa fungsi validasi berjalan sesuai harapan. Namun masih ada yang kurang, ketika ada yang tidak valid, error yang dikembalikan selalu sama, yaitu message Internal server error
.
Sebenarnya error 500 ini sudah sesuai jika muncul pada page yang sifatnya menampilkan konten. Pengguna tidak perlu tau secara mendetail mengenai detail error yang sedang terjadi. Mungkin dibuat saja halaman custom error agar lebih menarik.
Tapi untuk web service (RESTful API?), akan lebih baik jika errornya detail (terutama pada fase development), agar aplikasi consumer bisa lebih bagus dalam meng-handle error tersebut.
Nah, pada chapter selanjutnya kita akan belajar cara membuat custom error handler untuk meningkatkan kualitas error reporting.
- Echo, by Vishal Rana (Lab Stack), MIT license
- Validator v9, by Dean Karn (Go Playground), MIT license