1
1
package core
2
2
3
3
import (
4
+ "context"
4
5
"net/http"
5
6
6
7
"github.com/gin-gonic/gin"
7
-
8
8
"github.com/superproj/onex/pkg/errorsx"
9
9
)
10
10
11
- // ErrorResponse 定义了一个错误响应结构体.
11
+ // ValidatorFn 定义验证函数类型。用于对绑定的数据结构进行验证。
12
+ type ValidatorFn [T any ] func (context.Context , T ) error
13
+
14
+ // BindFn 定义绑定函数类型,接收通用类型参数并返回错误。
15
+ type BindFn func (any ) error
16
+
17
+ // ErrorResponse 定义错误响应结构体。
18
+ // 用于 API 请求中发生错误时,按照统一格式返回给客户端。
12
19
type ErrorResponse struct {
13
- // 理由
14
- Reason string `json:"reason,omitempty"`
15
- // 信息
16
- Message string `json:"message,omitempty"`
17
- // 元数据
18
- Metadata map [string ]string `json:"metadata,omitempty"`
20
+ Reason string `json:"reason,omitempty"` // 错误原因,标识错误类型
21
+ Message string `json:"message,omitempty"` // 错误的具体描述信息
22
+ Metadata map [string ]string `json:"metadata,omitempty"` // 元数据,包含额外的上下文信息
19
23
}
20
24
21
- func ShouldBindJSON (c * gin.Context , rq any ) error {
22
- return ReadRequest (c , rq , c .ShouldBindJSON )
25
+ // ShouldBindJSON 使用 JSON 格式的绑定函数绑定请求参数并执行验证。
26
+ func ShouldBindJSON [T any ](c * gin.Context , rq T , validators ... ValidatorFn [T ]) error {
27
+ return ReadRequest (c , rq , c .ShouldBindJSON , validators ... )
23
28
}
24
29
25
- func ShouldBindQuery (c * gin.Context , rq any ) error {
26
- return ReadRequest (c , rq , c .ShouldBindQuery )
30
+ // ShouldBindQuery 使用 Query 格式的绑定函数绑定请求参数并执行验证。
31
+ func ShouldBindQuery [T any ](c * gin.Context , rq T , validators ... ValidatorFn [T ]) error {
32
+ return ReadRequest (c , rq , c .ShouldBindQuery , validators ... )
27
33
}
28
34
29
- func ShouldBindUri (c * gin.Context , rq any ) error {
30
- return ReadRequest (c , rq , c .ShouldBindUri )
35
+ // ShouldBindUri 使用 URI 格式的绑定函数绑定请求参数并执行验证。
36
+ func ShouldBindUri [T any ](c * gin.Context , rq T , validators ... ValidatorFn [T ]) error {
37
+ return ReadRequest (c , rq , c .ShouldBindUri , validators ... )
31
38
}
32
39
33
- // ReadRequest 绑定参数、调用 Default() 初始化,并处理错误.
34
- func ReadRequest (c * gin.Context , rq any , bindFn func (any ) error ) error {
35
- // 使用特定参数绑定函数
40
+ // ReadRequest 是通用的请求绑定和验证工具函数。
41
+ // 它会对请求进行参数绑定,初始化默认值(如果目标结构体实现了 Default 接口),并执行验证函数(可选)。
42
+ func ReadRequest [T any ](c * gin.Context , rq T , bindFn BindFn , validators ... ValidatorFn [T ]) error {
43
+ // 调用绑定函数绑定请求数据
36
44
if err := bindFn (rq ); err != nil {
37
45
return err
38
46
}
39
47
40
- // 调用 Default() 方法(如果存在)
41
- if defaulter , ok := rq .(interface { Default () }); ok {
48
+ // 如果目标结构体实现了 Default 接口,则调用其 Default 方法设置默认值
49
+ if defaulter , ok := any ( rq ) .(interface { Default () }); ok {
42
50
defaulter .Default ()
43
51
}
44
52
53
+ // 遍历所有验证函数并执行它们
54
+ for _ , validator := range validators {
55
+ if validator == nil { // 跳过 nil 的验证函数
56
+ continue
57
+ }
58
+ if err := validator (c .Request .Context (), rq ); err != nil {
59
+ return err
60
+ }
61
+ }
62
+
45
63
return nil
46
64
}
47
65
48
- // WriteResponse 处理响应的函数.
66
+ // WriteResponse 是统一的响应处理函数。
67
+ // 根据返回值是否发生错误,返回成功响应或错误响应。
49
68
func WriteResponse (c * gin.Context , result any , err error ) {
50
- // 判断错误是否存在
69
+ // 如果发生错误,生成错误响应
51
70
if err != nil {
52
- errx := errorsx .FromError (err ) // 从错误中获取详细信息
53
- // 返回错误响应
71
+ errx := errorsx .FromError (err ) // 从错误对象中解析详细错误信息
54
72
c .JSON (errx .Code , & ErrorResponse {
55
73
Reason : errx .Reason ,
56
74
Message : errx .Message ,
@@ -59,6 +77,6 @@ func WriteResponse(c *gin.Context, result any, err error) {
59
77
return
60
78
}
61
79
62
- // 返回正常响应
80
+ // 如果没有错误,生成成功响应
63
81
c .JSON (http .StatusOK , result )
64
82
}
0 commit comments