You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.3 KiB
84 lines
2.3 KiB
1 year ago
|
package rsp
|
||
|
|
||
|
import (
|
||
|
"github.com/labstack/echo/v4"
|
||
|
"net/http"
|
||
|
)
|
||
|
|
||
|
// GuardFunc 参数守卫函数前面
|
||
|
type GuardFunc[T any] func(c echo.Context, req *T) error
|
||
|
|
||
|
// ServeFunc 参数处理函数签名
|
||
|
type ServeFunc[T any, R any] func(c echo.Context, req *T) (*R, error)
|
||
|
|
||
|
// ServeWithDataFunc 参数处理函数签名,支持自定义数据
|
||
|
type ServeWithDataFunc[T any, R any, O any] func(c echo.Context, req *T, opt O) (*R, error)
|
||
|
|
||
|
// RespondFunc 数据响应函数前面
|
||
|
type RespondFunc[R any] func(c echo.Context, res *R) error
|
||
|
|
||
|
// Handle 通用 CRUD 函数构造器,具体参数与函数 HandleWithData 保持一致
|
||
|
func Handle[T any, R any](guard GuardFunc[T], serve ServeFunc[T, R], respond ...RespondFunc[R]) echo.HandlerFunc {
|
||
|
return HandleWithData[T, R, any](guard, func(c echo.Context, req *T, opt any) (*R, error) {
|
||
|
return serve(c, req)
|
||
|
}, nil, respond...)
|
||
|
}
|
||
|
|
||
|
// HandleWithData 通用 CRUD 函数构造器,可以预置数据
|
||
|
//
|
||
|
// 参数 guard 可以为空值,表示无参数守卫;
|
||
|
// 参数 serve 必传;
|
||
|
// 参数 data 为自定义数据,该值最好不可被修改;
|
||
|
// 参数 respond 为自定义响应函数,若未指定,内部将使用 Ok 或 Created 来响应结果。
|
||
|
func HandleWithData[T any, R any, D any](guard GuardFunc[T], serve ServeWithDataFunc[T, R, D], data D, respond ...RespondFunc[R]) echo.HandlerFunc {
|
||
|
if serve == nil {
|
||
|
panic("miss ServeFunc")
|
||
|
}
|
||
|
return func(c echo.Context) error {
|
||
|
var req T
|
||
|
if err := c.Bind(&req); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if err := c.Validate(&req); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if guard != nil {
|
||
|
err := guard(c, &req)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
res, err := serve(c, &req, data)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for _, send := range respond {
|
||
|
if send != nil {
|
||
|
return send(c, res)
|
||
|
}
|
||
|
}
|
||
|
// 我们认为凡是 PUT 请求,都是创建数据
|
||
|
// 所以这里使用 Created 函数来响应数据。
|
||
|
if c.Request().Method == http.MethodPut {
|
||
|
return Created(c, res)
|
||
|
}
|
||
|
return Ok(c, res)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Bind[T any](c echo.Context, guards ...GuardFunc[T]) (*T, error) {
|
||
|
var req T
|
||
|
if err := c.Bind(&req); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if err := c.Validate(&req); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
for _, guard := range guards {
|
||
|
if err := guard(c, &req); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
return &req, nil
|
||
|
}
|