在Go语言中,中间件(Middleware)是一种常见的模式,用于在处理HTTP请求时执行一些通用的逻辑,如身份验证、日志记录、错误处理等。当多个业务需要共用同一复杂逻辑时,可以通过以下几种方式优雅地处理:
将复杂的逻辑封装成一个中间件函数,然后在需要的地方使用这个中间件。这种方式适用于需要在多个路由或处理函数中共享同一逻辑的场景。
package main
import (
"fmt"
"net/http"
)
// 复杂的逻辑封装成中间件
func complexMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在这里执行复杂的逻辑
fmt.Println("Executing complex logic...")
// 调用下一个处理函数
next.ServeHTTP(w, r)
})
}
func handler1(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 1")
}
func handler2(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 2")
}
func main() {
mux := http.NewServeMux()
// 使用中间件
mux.Handle("/path1", complexMiddleware(http.HandlerFunc(handler1)))
mux.Handle("/path2", complexMiddleware(http.HandlerFunc(handler2)))
http.ListenAndServe(":8080", mux)
}
如果复杂的逻辑需要根据不同的业务场景进行定制,可以使用闭包来封装逻辑,并返回一个中间件函数。
package main
import (
"fmt"
"net/http"
)
// 使用闭包封装复杂逻辑
func complexMiddlewareWithParams(param string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在这里执行复杂的逻辑,并使用传入的参数
fmt.Printf("Executing complex logic with param: %s\n", param)
// 调用下一个处理函数
next.ServeHTTP(w, r)
})
}
}
func handler1(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 1")
}
func handler2(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 2")
}
func main() {
mux := http.NewServeMux()
// 使用带参数的中间件
mux.Handle("/path1", complexMiddlewareWithParams("param1")(http.HandlerFunc(handler1)))
mux.Handle("/path2", complexMiddlewareWithParams("param2")(http.HandlerFunc(handler2)))
http.ListenAndServe(":8080", mux)
}
如果复杂的逻辑涉及到多个步骤或需要维护一些状态,可以将逻辑封装在一个结构体中,并通过方法来实现中间件。
package main
import (
"fmt"
"net/http"
)
// 定义结构体封装复杂逻辑
type ComplexLogic struct {
Param string
}
// 中间件方法
func (cl *ComplexLogic) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在这里执行复杂的逻辑,并使用结构体的字段
fmt.Printf("Executing complex logic with param: %s\n", cl.Param)
// 调用下一个处理函数
next.ServeHTTP(w, r)
})
}
func handler1(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 1")
}
func handler2(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 2")
}
func main() {
mux := http.NewServeMux()
// 创建结构体实例
cl1 := &ComplexLogic{Param: "param1"}
cl2 := &ComplexLogic{Param: "param2"}
// 使用结构体的中间件方法
mux.Handle("/path1", cl1.Middleware(http.HandlerFunc(handler1)))
mux.Handle("/path2", cl2.Middleware(http.HandlerFunc(handler2)))
http.ListenAndServe(":8080", mux)
}
如果复杂的逻辑涉及到更多的功能,如身份验证、日志记录、限流等,可以考虑使用一些成熟的第三方中间件库,如gorilla/mux
、negroni
等。这些库提供了丰富的中间件功能,可以帮助你更高效地处理复杂的逻辑。
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func complexMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 在这里执行复杂的逻辑
fmt.Println("Executing complex logic...")
// 调用下一个处理函数
next.ServeHTTP(w, r)
})
}
func handler1(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 1")
}
func handler2(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Handler 2")
}
func main() {
r := mux.NewRouter()
// 使用中间件
r.Use(complexMiddleware)
r.HandleFunc("/path1", handler1)
r.HandleFunc("/path2", handler2)
http.ListenAndServe(":8080", r)
}
通过将复杂的逻辑封装成中间件函数、使用闭包、结构体或第三方库,可以优雅地在多个业务中共享同一复杂逻辑。选择哪种方式取决于具体的业务需求和代码结构。