进阶 www.iris-go.com 2026-10-20 02:39:14 · 21 阅读
第36章 Iris 框架请求校验实战
# 第36章 请求校验
学习如何在 Iris 中校验请求。
## 基础校验
```go
package main
import (
"github.com/kataras/iris/v12"
"github.com/go-playground/validator/v10"
)
type User struct {
Name string `json:"name" validate:"required,min=2"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"required,gte=0,lte=130"`
Password string `json:"password" validate:"required,min=8"`
}
func main() {
app := iris.New()
validate := validator.New()
app.Post("/users", func(ctx iris.Context) {
var user User
if err := ctx.ReadJSON(&user); err != nil {
ctx.StopWithError(iris.StatusBadRequest, err)
return
}
if err := validate.Struct(user); err != nil {
if validationErrors, ok := err.(validator.ValidationErrors); ok {
errors := make([]string, len(validationErrors))
for i, e := range validationErrors {
errors[i] = e.Field() + " failed " + e.Tag() + " validation"
}
ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
Title("Validation Error").
Detail("One or more fields failed validation").
Key("errors", errors))
return
}
}
ctx.JSON(iris.Map{
"message": "User validated successfully",
"user": user,
})
})
app.Listen(":8080")
}
```
自定义验证
go
type Registration struct {
Username string `json:"username" validate:"required,min=3"`
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=8"`
ConfirmPassword string `json:"confirm_password" validate:"required,eqfield=Password"`
}
func passwordsMatch(fl validator.FieldLevel) bool {
return fl.Field().String() == fl.Parent().FieldByName("Password").String()
}
func main() {
app := iris.New()
validate := validator.New()
// 注册自定义验证
validate.RegisterValidation("passwords_match", passwordsMatch)
app.Post("/register", func(ctx iris.Context) {
var reg Registration
if err := ctx.ReadJSON(®); err != nil {
ctx.StopWithError(iris.StatusBadRequest, err)
return
}
if err := validate.Struct(reg); err != nil {
ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem().
Title("Validation Error").
DetailErr(err))
return
}
ctx.JSON(iris.Map{
"message": "Registration successful",
})
})
app.Listen(":8080")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
跨字段验证 go type DateRange struct { Start time.Time `json:"start" validate:"required"` End time.Time `json:"end" validate:"required,gtfield=Start"` } app.Post("/daterange", func(ctx iris.Context) { var dates DateRange if err := ctx.ReadJSON(&dates); err != nil { ctx.StopWithError(iris.StatusBadRequest, err) return } if err := validate.Struct(dates); err != nil { ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem(). Title("Validation Error"). DetailErr(err)) return } ctx.JSON(iris.Map{ "message": "Date range is valid", "dates": dates, }) }) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
跨字段验证 go type DateRange struct { Start time.Time `json:"start" validate:"required"` End time.Time `json:"end" validate:"required,gtfield=Start"` } app.Post("/daterange", func(ctx iris.Context) { var dates DateRange if err := ctx.ReadJSON(&dates); err != nil { ctx.StopWithError(iris.StatusBadRequest, err) return } if err := validate.Struct(dates); err != nil { ctx.StopWithProblem(iris.StatusBadRequest, iris.NewProblem(). Title("Validation Error"). DetailErr(err)) return } ctx.JSON(iris.Map{ "message": "Date range is valid", "dates": dates, }) }) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
最佳实践验证规则:使用描述性标签、实现自定义规则、处理跨字段验证、记录需求、测试边缘情况。错误处理:提供清晰的提示信息、返回正确的状态码、记录验证错误、处理所有场景、记录错误文档。安全性:验证所有输入、设置合适的限制、处理特殊字符、监控验证过程、防止注入。性能:缓存验证器、优化规则、处理超时、监控性能、释放资源。