web中间件_HTTP中间件机制实现与原理 - 从零开始写GO-API框架
大家好,很高兴您能阅读这篇文章。
最近在投稿公众号时发现从未做过自我介绍,首先请允许我介绍一下自己。
我叫张晓亮,就职于新浪微博,Golang的忠实粉丝,平时的爱好看看书、撸撸码,典型的程序员性格,最近喜欢上写博客,发现不仅能从中了解到很多细节,也能帮助到其他人。
引言
因golang内置的net/http天生就支持http中间件机制,所以即使不使用开源web框架,我们也可以写出扩展性很好的应用。
一个好的中间件有一个责任就是可插拔并且自足,这就意味着你可以在接口级别嵌入你的中间件他就能直接运行,且不会影响你的编码方式,这不是框架,仅仅是在请求处理里面的一层而已。
可以想象每一个中间件都是一层洋葱皮,其中每一个中间件都可以改变请求响应,我们可以很自然的把不同的逻辑放到不同的洋葱皮里,让代码更符合单一原则。
你可以使用中间件做什么?
1、重置HTTP请求路由2、统一安全限制、信息上报3、Header操作、http请求认证4、屏蔽爬虫5、提供调试信息6、请求日志记录还有很多,可以自行发掘下
中间件通常会是一小段代码,它可以接受一个请求,对其进行处理,每个中间件只处理一件事,完成后将其传递给下一层或最终处理。这样就做到了程序的解耦。
如果没有中间件我们必须在最终处理程序中来完成这个逻辑操作,这无疑会造成你现有业务逻辑的臃肿和代码复用率不高的问题.
http中间件使用案例
惯例我们来看使用中间件的案例:
测试代码
func middlewareLoger() koala.HandlerFunc {return func(ctx *koala.Context) {fmt.Printf("%+v", ctx.Req)fmt.Println("middloger 中间件")// fmt.Printf("%+V 进入到中间件了", ctx)}}func main() { app := koala.New()app.Use(middlewareLoger())app.Add("GET", "/profile/xiaoliang", func(ctx *koala.Context) {ctx.Text("profile.xiaoliang")})}
web请求地址:http://127.0.0.1:8080/profile/xiaoliang1 输出
[KOALA-DEBUG][启动中]Add GET /profile/xiaoliang Add GET /profile/xiaoliang1 Add GET /member/:id [KOALA-DEBUG]监听端口[:8080][KOALA-DEBUG][服务启动成功]此处是中间件输出信息&{Method:GET URL:/profile/xiaoliang1 Proto:HTTP/1.1 ...... ctx:0xc00005c4c0}middlewareLoger 中间件
实现扩展HTTP中间件机制
以上讲解了中间件的相关基础知识,也看了使用案例,下面我们来实现一下中间件是如何嵌入到web框架中,并以此来实现各种解耦的功能。
先来看张图
可以看看,如果我们把路由函数xiaoliang看做汉堡里的肉饼,中间件函数看成面包,那么middlewareLoger包住了肉饼。
这里可以实现很多层的中间件,为了实现简单,我们这里就做一层。
撸代码
准备工作完成,我们开始撸代码吧。我比较喜欢这个环节_.
以下代码逻辑,是按照实现先后顺序展示
代码位置:https://github.com/zl8762385/koala/blob/master/v1/koala.go
type Middleware interface {}// 定义 koala引擎结构type Koala struct {...代码折叠// 中间件middleware []HandlerFunc}// 注册中间件func(k *Koala) Use(m ...Middleware) {for i := range m {if m[i] != nil { // 注册中间件放入切片数组k.middleware = append(k.middleware, warpMiddleware(m[i]))}}}
处理不同中间件类型,在这里我们就很容易扩展HTTP中间件机制了
目前仅实现request,后续会陆续扩展
func warpMiddleware(m Middleware) HandlerFunc { // 断言当前函数类型switch m:= m.(type) {case HandlerFunc:return mcase func (*Context):return mdefault:fmt.Printf("%+V", m)panic("没找到相关中间件")}}
next.ServHTTP中间件用户态实现
// 实现net/http 需要的servehttp服务func (k *Koala) ServeHTTP(rw http.ResponseWriter, req *http.Request) { ...代码折叠// 执行相关操作ctx.Next()...代码折叠}
代码位置:https://github.com/zl8762385/koala/blob/master/v1/context.go
// 首先处理中间件,然后处理路由句柄func (c *Context) Next() {// http中间件处理c.middleware()// 路由映射处理c.koala.router().HandlerRouter(c)}// 执行HTTP中间件func (c *Context) middleware() {for m := range c.koala.middleware{ // c http上下文传递给注册的中间件函数,这时候已经拿到了用户侧web请求数据,可以进行响应的逻辑操作c.koala.middleware[m](c)}}
晓亮嘚吧嘚,请听下回分解
看到这里大伙也发现中间件代码部分实际上不复杂,复杂是一些概念上的知识。
作者原是phper,对于中间件的了解基本属于黑洞。所以这章基础知识讲解的多了一些,一自己巩固知识点,二让看文章的您也可以跟着我的节奏复习一下。
文章还会陆续更新,最近在研究数据库连接池相关知识,准备利用这个框架的轮廓,我们在写一个关于连接池相关的包。
作者本人golang相关知识有限,如讲解不正确,还希望大牛们能帮忙指正,晓亮先感谢您~
web中间件_HTTP中间件机制实现与原理 - 从零开始写GO-API框架相关推荐
- WEB服务器和中间件
一.WEB服务器 WEB服务器也称为WWW(WORLD WIDE WEB)服务器,主要功能是提供网上信息浏览服务. WWW 采用的是浏览器/服务器结构,其作用是整理和储存各种WWW资源,并响应客户端软 ...
- 渗透测试-WEB安全梳理-中间件(apache、IIS、tomcat、weblogic、websphere、jboos、nginx)
渗透测试-WEB安全梳理-中间件(apache.IIS.tomcat.weblogic.websphere.jboos.nginx) WEB安全梳理-中间件(apache.IIS.tomcat.web ...
- Session | web应用的session机制、session的实现原理
目录 一:web应用的session机制 二:session的实现原理 一:web应用的session机制 (1)什么是会话? ①会话对应的英语单词:session ②用户打开浏览器,进行一系列操作, ...
- web容器、中间件以及web服务器的区别
一.web容器 1.web容器的介绍 web容器是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求.实际上,Web容器是一种服务程序,给处于其中的应用程序 ...
- php raabitmq中间件_rabbitMQ消息中间件环境配置及原理了解
视频教程 一.Docker 入门 Docker是什么? Docker 是一个开源的应用容器引擎,你可以将其理解为一个轻量级的虚拟机,开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任 ...
- java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍
本文主要向大家介绍了JAVA语言之Java NIO的工作机制和实现原理介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 前言 本文只简单介绍NIO的原理实现和基本工作流程 I/O和 ...
- 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结
Angular 的数据绑定采用什么机制,详述原理? 脏检查机制.阐释脏检查机制,必须先了解如下问题. 单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别? ng-bind 单向数据绑 ...
- php的工作原理,PHP的运行机制和工作原理的内容
这篇文章给大家介绍的内容是关于PHP的运行机制和工作原理的内容,有着一定的参考价值,有需要的朋友可以参考一下. 一.PHP设计理念及特点 多进程模型:由于PHP是多进程模型,不同请求间互不干涉,这样保 ...
- 最容易理解的反射机制的底层原理
看了好多关于Java反射机制的文章,大多都太过官方,消化起来比较稍显费劲,本篇,我会依据自己的理解去阐述什么是Java的反射机制,反射用在什么地方,以及怎么来使用? 开篇前,我们还是要了解一下,什么是 ...
最新文章
- unity android ndk的作用,Unity中编写Android下使用的so插件
- [一天一个小知识]instanceof
- Deep-Learning-with-Python] 文本序列中的深度学习
- 让皮肤变水嫩的15条小妙招 - 健康程序员,至尚生活!
- Tomcat 之 启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099;...
- HDU 2064:汉诺塔III
- P3250 [HNOI2016]网络(利用堆建线段树 + 树剖)
- python中递归函数写法_python中递归函数如何创建
- SAMBA用户访问指定的目录
- lodop php 快递单_lodop打印控件打印申通快递单
- 如何通过Facebook主页获得用户的邮箱
- pycharm 查看 python源代码
- python_并发编程
- RTL8367/N/RB/S/SC系列千兆交换机方案选型参考
- 2021物联网国赛zigbee点对点通讯——G卷
- SpaceX SN8飞船爆炸,马斯克:已拿到全部所需数据,火星,我们来了!
- 平安好医生掉队,是选了更难的那条路
- 实践中如何优化MySQL(精)
- 人工智能时代的工作、学习和生活---《人工智能》阅读笔记
- 安卓AES加解密(兼容Android7.0)