ghttp

package
v0.0.0-...-bf85ca1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2022 License: Apache-2.0 Imports: 13 Imported by: 0

README

3. http-server filter 中间件的设计

http服务的启动过程与上述grpc十分类似,其中亮点是,根据业务需求,http-server封装了mux,在提供基础服务:路由、统一化http参数获取、自动打解包等等等基础上,增加了链式请求过滤器的支持。

3.1 链式http请求过滤的实现

可在http/filter.go中看到针对过滤器和业务处理函数接口的定义

// HandleFunc 业务处理函数接口
type HandleFunc func(controller *GRegisterController) (err error)

// Filter 过滤器(拦截器),根据dispatch处理流程进行上下文拦截处理
type Filter func(controller *GRegisterController, f HandleFunc) (err error)

// Chain 链式过滤器
type Chain []Filter

框架会为http服务分配一个filter链,即上述的Chain结构,

// http处理函数
func getGloryHttpHandler(handler func(*GRegisterController) error, req, rsp interface{}, filters []Filter) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {

		retPkg := rspImpPackage

		// recovery
		...

		// 创建针对当前接口的过滤器chain
		chain := Chain{}
		chain.AddFilter(filters) // 注册过滤器

		tRegisterController := GRegisterController{
			Ctx: r.Context(),
			R:   r,
		}
		// 处理 req
		// 处理 rsp
			// 执行业务函数
		if err := chain.Handle(&tRegisterController, handler); err != nil {
			retPkg.SetErrorPkg(w, err)
			return
		}
		// 最终回包
    ...
		return
	}
}

可见,在上述函数中,将用户传入的自定义filter过滤函数,放在chain内形成filter链,再由chain调用Handle 函数,逐个执行链内所有filter,通过所有过滤的请求才最终被执行业务逻辑,否则按照filter逻辑返回。

http/filter.go: Handle函数内的实现

//多个Filter,递归执行
	lastI := n - 1
	return func(controller *GRegisterController, f HandleFunc) error {

		var (
			chainFunc HandleFunc
			curI      int
		)
		chainFunc = func(controller *GRegisterController) error {
			if curI == lastI {
				return f(controller)
			}
			curI++
			err := (*fc)[curI](controller, chainFunc)
			curI--
			return err
		}
		return (*fc)[0](controller, chainFunc)
	}(controller, f)

3.2 链式http请求过滤的使用

// 测试用filter 如果input字段为-2则报错
func myFilter2(controller *ghttp.GRegisterController, f ghttp.HandleFunc) error {
	req, ok := controller.Req.(*gloryHttpReq)
	if !ok {
		log.Error("req type err")
		return errors.New("req type err")
	}

	if req.Input[0] == -2 {
		log.Error("filting because input == -2")
		return errors.New("filting because input == -2")
	}
	err := f(controller)
	return err
}

func main() {
	gloryServer := glory.NewServer()
	httpService := service.NewHttpService("httpDemo")
	httpService.RegisterRouter("/testwithfilter/{hello}/{hello2}", testHandler, &gloryHttpReq{}, &gloryHttpRsp{}, "POST", myFilter1, myFilter2)
	gloryServer.RegisterService(httpService)
	gloryServer.Run()
}

可按照此方法,将,myfilter1,myfilter2等过滤器注册在httpService上,从而针对请求进行过滤。

在GoOnline项目中,此filter被广泛应用于auth部分token鉴权。

Documentation

Index

Constants

View Source
const (
	UnsetHttpCode          = httpCode(0)
	DefaultHttpSuccessCode = httpCode(200)
	DefaultHttpErrorCode   = httpCode(500)
)

Variables

This section is empty.

Functions

func NewHttpRegister

func NewHttpRegister()

func NoopFilter

func NoopFilter(controller *GRegisterController, f HandleFunc) (err error)

NoopFilter 空Filter实现

func RegisterRouter

func RegisterRouter(path string, r *mux.Router, handler func(*GRegisterController) error, req, rsp interface{}, method string, filters []Filter)

入口函数

func RegisterRspPackage

func RegisterRspPackage(rspUserImplPackageFactory RspPackageFactory)

自定义回包函数

func RegisterWSRouter

func RegisterWSRouter(path string, r *mux.Router, handler func(*GRegisterWSController))

Types

type Chain

type Chain []Filter

Chain 链式过滤器

func (*Chain) AddFilter

func (fc *Chain) AddFilter(f []Filter)

func (*Chain) Handle

func (fc *Chain) Handle(controller *GRegisterController, f HandleFunc) (err error)

Handle 链式过滤器递归处理流程

type DefaultRspPackage

type DefaultRspPackage struct {
}

func (*DefaultRspPackage) SetErrorPkg

func (rpkg *DefaultRspPackage) SetErrorPkg(w http.ResponseWriter, err error, retCode httpCode)

func (*DefaultRspPackage) SetSuccessPkg

func (rpkg *DefaultRspPackage) SetSuccessPkg(w http.ResponseWriter, result interface{}, retCode httpCode)

type Filter

type Filter func(controller *GRegisterController, f HandleFunc) (err error)

Filter 过滤器(拦截器),根据dispatch处理流程进行上下文拦截处理

type FomattedRspPackage

type FomattedRspPackage struct {
	Retcode int32       `json:"retcode"`
	Retmsg  string      `json:"retmsg"`
	Result  interface{} `json:"result"`
}

FomattedRspPackage 框架提供的格式化回包,包含三个字段,与下面的 DefaultRspPackage 选择使用

func (*FomattedRspPackage) SetErrorPkg

func (rpkg *FomattedRspPackage) SetErrorPkg(w http.ResponseWriter, err error, retCode httpCode)

func (*FomattedRspPackage) SetSuccessPkg

func (rpkg *FomattedRspPackage) SetSuccessPkg(w http.ResponseWriter, result interface{}, retCode httpCode)

type GRegisterController

type GRegisterController struct {
	// Req 存放请求的数据
	Req interface{}
	// Rsp 用来设置回包
	Rsp interface{}
	// R 暴露 http.Request
	R *http.Request
	// W 暴露 http.ResponseWriter
	W http.ResponseWriter
	// VarsMap url 变量
	VarsMap map[string]string
	// RspCode 返回http状态码,不设则使用默认成功、失败状态码
	RspCode httpCode
	// IfNeedWrite 为false时,框架将不会向 http.ResponseWriter中写入值,用户需自主完成返回值的写入
	// 默认为true
	IfNeedWrite bool
}

func (*GRegisterController) GetReqData

func (trc *GRegisterController) GetReqData(r *http.Request) error

获取请求参数并进行参数校验

func (*GRegisterController) Key

func (trc *GRegisterController) Key() string

Key is made of $(path)_$(method)

type GRegisterWSController

type GRegisterWSController struct {
	WSConn *websocket.Conn
	R      *http.Request
}

type HandleFunc

type HandleFunc func(controller *GRegisterController) (err error)

HandleFunc 业务处理函数接口

type ResultAndOKRspPackage

type ResultAndOKRspPackage struct {
	Result interface{} `json:"result"`
	OK     bool        `json:"ok"`
}

ResultAndOKRspPackage contains ok and result

func (*ResultAndOKRspPackage) SetErrorPkg

func (rpkg *ResultAndOKRspPackage) SetErrorPkg(w http.ResponseWriter, err error, retCode httpCode)

func (*ResultAndOKRspPackage) SetSuccessPkg

func (rpkg *ResultAndOKRspPackage) SetSuccessPkg(w http.ResponseWriter, result interface{}, retCode httpCode)

type RspPackage

type RspPackage interface {
	SetSuccessPkg(w http.ResponseWriter, msg interface{}, retCode httpCode) // 成功回包
	SetErrorPkg(w http.ResponseWriter, err error, retCode httpCode)         // 错误回包
}

func NewDefaultRspPackage

func NewDefaultRspPackage() RspPackage

func NewFomattedRspPackage

func NewFomattedRspPackage() RspPackage

func NewResultAndOKRspPackage

func NewResultAndOKRspPackage() RspPackage

type RspPackageFactory

type RspPackageFactory func() RspPackage

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL