Documentation
¶
Overview ¶
Package handler 提供声明式 HTTP handler 包装器:把 auth 策略 + 资源注入 + 错误归一化从业务 handler 上移到包装器,handler 只关心 (ctx, req) => (resp, error)。
声明式声明"这个 handler 需要什么"(认证策略、依赖),由包装器统一注入, 业务函数保持纯净——只接收 ctx 和解析好的请求,返回响应或 error。
这其实是 pkg/callbacks + pkg/middleware/auth + pkg/afterwork + DI 组合成一个 ergonomic 的 handler 装饰器:
- WithAuth(policy):在调业务函数前做认证/授权,User 注入 ctx;
- WithInject(deps):把任意依赖(DB、cache、client...)装入 ctx 供 handler 取;
- WithAfterwork:挂上 afterwork.Middleware,handler 里 afterwork.Defer(...) 投递的响应后副作用在响应返回后跑完;
- WithRatelimit:声明式限流;
- WithMiddleware:挂任意标准中间件(func(http.Handler) http.Handler)于最外层—— 核心不依赖 contrib,故可即插即用如 contrib/wasm 的过滤器等;
- 返回的 error 自动经 errors.WriteHTTP 归一化为统一错误响应。
用法:
type CreateOrderReq struct { UserID string; Sku string }
type CreateOrderResp struct { OrderID string }
h := handler.New[CreateOrderReq, CreateOrderResp](
"POST /orders",
func(ctx context.Context, req *CreateOrderReq) (*CreateOrderResp, error) {
user := auth.GetUserFromContext(ctx) // 认证后注入
db := handler.MustGet[*sql.DB](ctx, "db") // 依赖注入
id, err := createOrder(ctx, db, user.ID(), req.Sku)
if err != nil { return nil, err }
afterwork.Defer(ctx, func(c context.Context) { // 响应后副作用
_ = webhook.Notify(c, orderEvent{id})
})
return &CreateOrderResp{OrderID: id}, nil
},
handler.WithAuth(authPolicy),
handler.WithInject("db", orderDB),
handler.WithAfterwork(),
)
mux.Handle("/orders", h)
泛型参数 I 是请求体类型(指针),O 是响应体类型(指针),均通过 JSON 编解码。 请求方法固定为方法字段(Method);query/path 参数由调用方自行从 *http.Request 取(本包装器只管 body + auth + error + 响应后副作用)。
Index ¶
- func Get[T any](ctx context.Context, name string) (T, bool)
- func MustGet[T any](ctx context.Context, name string) T
- type AuthPolicy
- type Func
- type Handler
- type Option
- func WithAfterwork(opts ...afterwork.Option) Option
- func WithAuth(p AuthPolicy) Option
- func WithInject(name string, dep any) Option
- func WithMethod(m string) Option
- func WithMiddleware(mw ...func(http.Handler) http.Handler) Option
- func WithRatelimit(l ratelimit.Limiter, keyFn ratelimit.KeyFunc) Option
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AuthPolicy ¶
AuthPolicy 声明式认证策略:由调用方实现,返回认证后的 User 或 error。 通常包装 pkg/middleware/auth.Authenticator.Authenticate + Authorizer.Authorize。 返回的 User 会被注入 ctx(供业务函数用 auth.GetUserFromContext 取出)。 resource/action 用于授权检查;返回 nil User 表示匿名访问(允许则放行)。
type Func ¶
Func 业务 handler 函数签名:接收 ctx 和解析好的请求体,返回响应体或 error。 ctx 已注入认证后的 User(若有 WithAuth)和声明式依赖(若有 WithInject)。
type Handler ¶
Handler 包装后的 http.Handler。实现 http.Handler 接口,可直接挂到 mux。
type Option ¶
type Option func(*config)
Option 配置 Handler。
func WithAfterwork ¶
WithAfterwork 挂载 afterwork.Middleware:handler 里 afterwork.Defer(...) 投递的响应后副作用,在响应返回后由中间件等待跑完。opts 透传给 afterwork。
func WithAuth ¶
func WithAuth(p AuthPolicy) Option
WithAuth 附加声明式认证策略。handler 执行前先调 policy: 失败则经 errors.WriteHTTP 返回错误响应;成功则把 User 注入 ctx。
func WithInject ¶
WithInject 注入一个命名依赖到 ctx,业务函数用 Get[T](ctx, name) 取出。 可多次调用注入多个依赖。
func WithMiddleware ¶
WithMiddleware 附加任意标准 HTTP 中间件(func(http.Handler) http.Handler),挂在包装链的 **最外层**——先于 ratelimit/afterwork/auth 执行,可提前短路(拒绝/改写)。多次传入或一次传多个时, **靠前的在更外层**(WithMiddleware(a, b) 中 a 包住 b 包住其余)。
核心不依赖 contrib,故通过这个通用口即插即用任意中间件——例如把 contrib/wasm 的过滤器绑上:
handler.New(method, fn,
handler.WithMiddleware(wasm.Middleware(mod)), // wasm 沙箱过滤器
handler.WithRatelimit(lim, keyFn),
)