我也学习Golang的HTTP中间件机制

这是原地址:https://huoding.com/2019/01/31/716

一般代码使用中间件是这样的:

package main
 
import (
	"net/http"
)
 
func foo(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("foo("))
		next(w, r)
		w.Write([]byte(")"))
	}
}
 
func bar(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("bar("))
		next(w, r)
		w.Write([]byte(")"))
	}
}
 
func test(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("test"))
}
 
func main() {
	http.Handle("/", foo(bar(test)))
	http.ListenAndServe(":8080", nil)
}

作者修改后是这样的:

package pipeline
 
import "net/http"
 
type Pipeline struct {
	middlewares []Middleware
}
 
type Middleware func(http.HandlerFunc) http.HandlerFunc
 
func New(ms ...Middleware) Pipeline {
	return Pipeline{ms}
}
 
func (p Pipeline) Pipe(ms ...Middleware) Pipeline {
	return Pipeline{append(p.middlewares, ms...)}
}
 
func (p Pipeline) Process(h http.HandlerFunc) http.HandlerFunc {
	for i := range p.middlewares {
		h = p.middlewares[len(p.middlewares)-1-i](h)
	}
 
	return h
}
 
...
 
func main() {
	http.Handle("/", pipeline.New(foo).Pipe(bar).Process(test))
	http.ListenAndServe(":8080", nil)
}

调用的思路清晰了,提高了代码的可复用性。为了进一步的理解,作了一些修改和注释。

package main
 
import (
	"net/http"
)
 
func foo(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("foo("))
		next(w, r)
		w.Write([]byte(")"))
	}
}
 
func bar(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("bar("))
		next(w, r)
		w.Write([]byte(")"))
	}
}
 
func 身份验证功能(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("身份验证("))
		next(w, r)
		w.Write([]byte(")"))
	}
}
 
func test(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("test"))
}
 
// ----------------------------------------------
 
func main() {
	http.Handle("/", new(foo).process(test))	
	http.Handle("/test", new(foo).pipe(bar).process(test))
	http.Handle("/chk", new(foo).身份验证().process(test))
	http.ListenAndServe(":8080", nil)
}
 
// -----------------------------------------------
 
type middleware func(http.HandlerFunc) http.HandlerFunc
 
type pipeline struct {
	middlewares []middleware
}
 
func new(ms ...middleware) pipeline {  //包一层方法
	return pipeline{append([]middleware(nil), ms...)}
}
 
func (p pipeline) pipe(ms ...middleware) pipeline { //包一层方法
	return pipeline{append(p.middlewares, ms...)}
}
 
func (p pipeline) 身份验证(ms ...middleware) pipeline { //包一层方法
	return pipeline{append(p.middlewares, 身份验证功能)}
}
 
func (p pipeline) process(h http.HandlerFunc) http.HandlerFunc { //进行处理,解包
	for i := range p.middlewares {
		h = p.middlewares[len(p.middlewares)-1-i](h)
	}
 
	return h
}

实际上中文函数名也运行得很好。

相关文章