go - 从 router.HandleFunc 调用返回多个中间件函数
问题描述
我正在使用 gorilla/mux 我有这个:
router.HandleFunc("/api/v1/register",h.makeRegisterNewUser(v)).Methods("POST")
看起来h.makeRegisterNewUser
像:
func (h Handler) makeRegisterNewUser(v interface{}) http.HandlerFunc {
type RespBody = ...;
type ReqBody = ...
return func(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&ReqBody)
// ...
json.NewEncoder(w).Encode(RespBody{});
}
}
我的问题是 - 有没有办法从 makeRegisterNewUser 返回多个 http.HandlerFuncs?像这样的东西:
router.HandleFunc("/api/v1/register",h.makeRegisterNewUser(v)).Methods("POST")
func (h Handler) makeRegisterNewUser(v interface{}) (http.HandlerFunc...) {
type RespBody = ...;
type ReqBody = ...
return func(w http.ResponseWriter, r *http.Request) {
// 1
}, func(w http.ResponseWriter, r *http.Request) {
// 2
}, func(w http.ResponseWriter, r *http.Request) {
// 3
}
}
我不确定中间件是否可以像在 Node.js Express 中那样在 Go 中链接。
解决方案
You can chain multiple http.Handler
using wrapper:
type Middleware struct {
next http.Handler
}
func (m Middleware) Wrap(handler http.Handler) http.Handler {
m.next = handler
return m
}
func (m Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// run your handler code here
// write error into w and return if you need to interrupt request execution
// call next handler
m.next.ServeHTTP(w, r)
}
Register chained wrappers and main handler:
h1 := Middleware{}
h2 := OtherMiddleware{}
router.Handle("/some_route", h1.Wrap(h2.Wrap(mainHandler))).Methods(http.MethodPost)
Request will execute h1
, h2
and finally mainHandler
.
For example, you can log request in h1
, authorize in h2
and keep business logic in mainHandler
.
推荐阅读
- javascript - 如何使用 Webpack 在 Vue 中设置全局 Sass 变量?
- react-native - 有一些 react-native-web react native-paper 吗?
- makefile - 避免扩展未使用的 makefile 目标的依赖关系
- android - Android jetpack 撰写观察 livedata
- vue.js - Vue材料日期选择器清除日期后更改格式
- c - calloc vs memset 一个显示结果,一个没有
- python - 如何将模块用作包的一部分并用作可直接执行的脚本?
- for-loop - 如何在实际结果之前阻止回收器视图重复循环项目?
- generics - 具有泛型参数类型的函数
- java - java.lang.UnsatisfiedLinkError:java.library.path 中没有 netty_transport_native_epoll_x86_64