Droplet——一款轻量的Golang应用层框架( 四 )

自定义中间件实现一个自定义中间件很简单,你只需要实现与 Hanler 类似的接口即可,下图是一个简单的中间件,它会用于检测输入参数是否需要 Quota 并执行相关逻辑:
type DemoMiddleware struct {// 继承基本的middleware,里面有用于实现处理链路的公共逻辑middleware.BaseMiddleware}func (mw *HttpInputMiddleware) Handle(ctx core.Context) error {if ck, ok := ctx.Input().(QuotaChecker); !ok {if err := ck.IsQuotaEnough(); err != nil {return err}}// 调用下一个中间件,有需要的话你也可以在响应返回后执行部分逻辑return mw.Handle(ctx)}func main() {// 如果你需要所有API都添加该中间件,可以在全局选项中将你的中间件编排 droplet.Option.Orchestrator = func(mws []core.Middleware) []core.Middleware {return append(mws, &DemoMiddleware{}) }...// 在单个API上启用 r.POST("/json_input/:id", ginwrap.Wraps(APIHandler,wrapper.Orchestrator(func(mws []core.Middleware) []core.Middleware {return append(mws, &DemoMiddleware{}) })))...}

Tips
Q: 为什么使用 Orchestrator 这样的形式来配置中间件,而非通过 Priorty 之类的权重来实现中间件的编排,这样在未来可以做到通过配置文件来调整中间件
A: 主要出于几个考虑
  1. 考虑现代微服务的架构下,多数业务无关的通用能力都会下沉到网关以及Mesh,因此一个服务的切面不会太多,在通过这样的方式来配置,成本是可以接受的 。
  2. 通过 Orchestrator 方式,用户还可以任意操作已添加的中间件,比如移除一些不必要的中间件,这是权重的方式无法做到的 。
  3. 当然如果以后有需要,现在的设计并不妨碍我们支持基于权重的方式
小结正如文中所说,Droplet 的核心目标是 提供位于应用层的、pipeline 形式的请求处理能力,并以此为基础提供了一些开箱即用的中间件 。它对项目带来的收益总结为几点:
  • 提供了框架无关的请求处理能力,这使得我们的服务更具韧性
  • 在应用层我们可以接触到 已序列化后的接口输入 以及 尚未序列化的接口输出 ,这使得我们在离业务更近的地方进行切面操作,进而将更多的通用代码沉淀到切面而降低业务代码的复杂度,更聚焦业务逻辑 。
希望 Droplet 能对你有所帮助与启发 。

经验总结扩展阅读