我也学习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
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值