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

时间:2016-11-16 22:42:39

标签: design-patterns go

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

例如,ASP.NET MVC允许这样做:

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

因此,在单独的类中实现的MyFilter()允许更好的代码组合和测试。

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

2 个答案:

答案 0 :(得分:1)

这种事情通常是在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)
    }
}

如您所见,中间件是一个功能:

  1. 接受http.HandlerFunc作为参数;
  2. 返回http.HandlerFunc;
  3. 调用传入的http.handlerFunc
  4. 使用这种基本技术,您可以“链接”任意数量的中间件:

    http.HandleFunc("/foo", another(middleware(handler)))
    

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

答案 1 :(得分:-1)

Revel(Go的Web框架)提供了类似的功能 拦截器(在动作调用之前或之后由框架调用的函数)。
这里描述的概念和实现:https://revel.github.io/manual/interceptors.html