如何实现Golang的http请求处理中间件(译)

youngsterxyf · · 4987 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

原文:Golang Http Handlers as Middleware

译者:youngsterxyf

大多数现代Web组件栈允许通过栈式/组件式中间件“过滤”请求,这样就能干净地从web应用中分离出横切关注点(译注:面向方面程序设计中的概念?)。 本周我尝试在Go语言的http.FileServer中植入钩子,发现实现起来十分简便,让我非常惊讶。

让我们从一个基本的文件服务器开始说起:

func main() {
    http.ListenAndServe(":8080", http.FileServer(http.Dir("/tmp")))
}

这段程序会在端口8080上开启一个本地文件服务器。那么我们该如何在这其中植入钩子从而能够在文件请求处理之前执行一些代码?来看一下http.ListenAndServe的方法签名:

func ListenAndServe(addr string, handler Handler) error

看起来http.FileServer返回了一个Handler---给定一个根目录就能知道如何处理文件请求。那我们来看看Handler接口:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

根据Go语言的接口原理,任何对象只要实现了ServeHTTP就是一个Handler。那么似乎我们需要做的事情就是构造一个自己的Handler---封装http.FileServer的处理流程。 Go语言的net/http标准库模块内置了一个帮助函数http.HandlerFunc,用于将普通函数转变为请求处理函数(handler):

type HandlerFunc func(ResponseWriter, *Request)

那么我们这样封装http.FileServer就可以了:

func OurLoggingHandler(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request)) {
        fmt.Println(*r.URL)
        h.ServeHTTP(w ,r)
    })
}

func main() {
    fileHandler := http.FileServer(http.Dir("/tmp"))
    wrappedHandler := OurLoggingHandler(fileHandler)
    http.ListenAndServe(":8080", wrappedHandler)
}

Go语言的net/http标准库模块有很多内置的处理函数,如TimeoutHandlerRedirectHandler, 可以相同的方式混合匹配使用。


译者推荐阅读


有疑问加站长微信联系(非本文作者)

本文来自:黑 * 白的博客

感谢作者:youngsterxyf

查看原文:如何实现Golang的http请求处理中间件(译)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

4987 次点击  ∙  3 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传