Go:如何使用中间件模式?

olp*_*phy 0 design-patterns go

我有一个仅在特定条件下执行的函数(例如role == 'Administrator')。现在,我使用“if”语句。但也可能存在条件数量较多且定义较长的“if”看起来不那么美观的情况。
Go 中(或与 Go 框架相关)是否有可用的机制允许实现中间件概念(动作过滤器)?

例如,ASP.NET MVC 允许执行以下操作:

[MyFilter]
public ViewResult Index()
{
     // Filter will be applied to this specific action method
}
Run Code Online (Sandbox Code Playgroud)

因此,在单独的类中实现 MyFilter() 可以更好地进行代码组合和测试。

更新: Revel(Go 的 Web 框架)提供与拦截器类似的功能(框架在操作调用之前或之后调用的函数):https://revel.github.io/manual/interceptors.html

Mar*_*oij 5

这种事情通常是用Go 中的中间件来完成的。最简单的是通过示例来展示:

package main

import (
    "fmt"
    "html"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", handler)
    http.HandleFunc("/foo", middleware(handler))

    log.Fatal(http.ListenAndServe(":8080", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
}

func middleware(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        r.URL.Path = "/MODIFIED"

        // Run the next handler
        next.ServeHTTP(w, r)
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,中间件是一个具有以下功能的函数:

  1. 接受 ahttp.HandlerFunc作为参数;
  2. 返回一个http.HandlerFunc;
  3. 调用http.handlerFunc传入的。

通过这种基本技术,您可以“链接”任意数量的中间件:

http.HandleFunc("/foo", another(middleware(handler)))
Run Code Online (Sandbox Code Playgroud)

这种模式有一些变体,大多数 Go 框架使用略有不同的语法,但概念通常是相同的。