04|中间件:如何提高框架的可拓展性?
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何通过中间件来提高框架的可拓展性。作者首先分析了现有代码中的优化点,强调了封装的重要性,并提出了通过中间件来实现代码扩展性的思路。接着,文章详细介绍了使用函数嵌套方式和pipeline思想分别实现中间件的方法。在使用函数嵌套方式时,作者通过封装核心业务逻辑和一层层添加装饰的方式实现了中间件的装饰器模式。然后,作者指出了函数嵌套方式存在的问题,并提出了使用pipeline思想改造中间件的方法。通过构建控制器链路的方式,实现了中间件和最终业务逻辑的结合,从而解决了函数嵌套方式存在的问题。文章通过改造node和Context数据结构,实现了控制器链路的注册和调用,同时提供了可变参数的设计,提高了注册入口的可用性。文章内容详实,逻辑清晰,对于想要深入了解中间件实现原理和优化方法的读者具有很高的参考价值。文章还演示了一个基本的中间件Recovery的实现,强调了中间件机制的重要性和应用价值。总的来说,本文通过具体的代码示例和思路分析,深入浅出地介绍了中间件的实现原理和优化方法,对于想要提高框架可拓展性的开发者具有一定的参考价值。
《手把手带你写一个 Web 框架》,新⼈⾸单¥59
全部留言(25)
- 最新
- 精选
- qinsi想到几个点: * 中间件的注册是有顺序的。比如最后才注册Recovery的话,pipeline中在Recovery前面的中间件如果panic了还是没法recover的 * 中间件需要显式调用ctx.Next(),如果写中间件时忘记了的话pipeline就断了。或许可以把中间件进一步拆成preRequest()和postRequest()两部分 * 中间件本质是装饰器模式,如果能像Java/Python里那样写装饰器标注的话可能意图更明显
作者回复: 1 是的,中间件注册有顺序,所以recovery是需要放在第一个。 2 这个是可以考虑,但是分成两个函数和现在用一个函数区别就是有的变量是没有办法写到两个函数中的,参数传递比较麻烦,比如我要打印请求时长,有一个变量,start_time, 需要在preRequest中写,postRequest中读,现在的方式就比较简单。分成两个函数就需要在postRequest中用参数传递之类的。 preRequest() ctxParam postRequest(ctxParam) 3 注释来表示装饰器,然后运行的时候读取注释来按需加载。这种方式也是行的,就是具体实现的时候需要读取“注释”来映射中间件,这里存在一个反射的逻辑,可能会降低效率。所以在golang中这种实现不多见。
2021-09-2047 - liyanfeng请教一下老师的UML图是用哪个软件画的哈?
作者回复: 可用工具很多,draw.io 金山文档都能用
2021-09-203 - The brain is a good thing这课程真的是,看一遍回本一次 - by 2023
作者回复: 感谢
2023-02-18归属地:广东2 - 友我看大家都说 allHandlers := append(c.middlewares, handlers...) 的写法有问题。其实没问题 因为每次扩容的时候 并没有赋值回去 即 :c.middwares := append(c.middlewares, handlers...) 所以每次都是拿未扩容的数组来 并不会出现覆盖的情况
作者回复: 之前确实是有问题的,已经修改过来了
2021-12-012 - liyanfeng这么好的课,大家快来买😄,熟悉加意外的感觉,真好
作者回复: 感谢支持,希望能帮助到你
2021-09-202 - 那些年支持!
作者回复: 感谢!
2021-12-131 - jayqiyoung如果每一节课后面的提问,下一节能够给些解答就好了
编辑回复: 后面有篇加餐,统一整理了一些作业题的思路,你可以看看~
2022-09-26 - 我在睡觉提一个问题,这里面 gourp机构题里面封装一个Group类型的parent链表有什么用意,我不需要这个parent字段也完全实现了同样的功能。
作者回复: 这个主要是使用上的方便,链式方式。 我可以多层嵌套group
2021-12-212 - 我在睡觉core.Use( middleware.Test1()) 老师你好。问一个问题, 为什么此处的Test1一定要定义成返回ControllerHandler匿名函数的函数,我实际直接把Test1定义成ControllerHandler类型的的函数执行起来也没有任何问题。
作者回复: 是这样的,这样设置的话,你可以在Test1的参数中带任何参数,然后在具体的ControllerHandler中使用这些参数,而如果你的Test1是ControllerHandler的话,参数就已经被固定了,后续扩展性就不是很好
2021-12-143 - 友老师请问 c.Next是可以捕获error的 在整个链路中如果一处地方抛出了error 但是在最顶层 ServeHTTP中的那个next如果返回nil 那么整条链路中的error会被忽略掉 我们只在 timeout中加入了 锁这个概念 其实这个其实这个应该可以抽出来 统一加上不允许重复写responseWriter
作者回复: 1 确实这里更严谨的写法是在所有中间件的c.Next() 都处理error 2 使用锁保证 responseWriter 只写一次肯定是可以的,但是我觉得这种只限制写一次反而也会有问题,会不会有场景有的控制器写内容,有的中间件写header头这种。这种限制可以加,但是加的时候估计要思考很清楚
2021-12-01