Go语言经典库使用分析,未完待续,欢迎扫码关注公众号
flysnow_org
或者网站http://www.flysnow.org/,第一时间看后续系列。觉得有帮助的话,顺手分享到朋友圈吧,感谢支持。
在我们编写web服务端程序的时候,我们可能会对一些甚至全部的Http Request统一处理,比如我们记录每个访问的Request,对提交的Form表单进行映射等,要达到这些目的,比较优雅的做法是Http 中间件。
中间件,顾名思义,强调的是中间,他是一种业务无关的,在正常的的业务handler处理前后的,独立的逻辑处理片段。一般调用顺序如下:
|
|
因为中间件非常独立,可以我们不用的时候,去掉即可;需要用的时候,加上,并不会修改真正的业务处理逻辑代码,可谓非常简洁方便。
这里我选用Gorilla Handlers这个中间件库演示如何使用和定义一个中间件,这一篇主要讲Gorilla Handlers的使用,下一篇会讲Gorilla Handlers里每个中间件的实现原理。
安装
Gorilla Handlers是一个很简单,但是很有代表性的中间件库,所以拿他来分析,更容易理解handler中间件。在使用之前,我们要先安装,该中间件库已经托管在Github上,所以我们直接使用go get即可。
|
|
安装之后,我们在代码里使用如下代码即可导入使用。
|
|
Gorilla Handlers以函数的方式提供了好几种中间件,比如CombinedLoggingHandler、CompressHandler、ContentTypeHandler、LoggingHandler等,下面我们就一一介绍他们。
LoggingHandler
我们应该都用过Nginx,Nginx的访问日志,类似于如下这样:
|
|
从中我们可以看到访问的什么资源,使用的什么协议,返回的HTTP状态以及请求的大小是多少,这种一种日志风格,和Apache Common Log Format很像,LoggingHandler中间件就是帮我们做这个事情的。
它可以记录request的日志,输出到一个io.Writer里。
|
|
我这里的io.Writer是一个os.Stdout,也就是标准的控制台输出,所以我们访问http://localhost:1234/
的时候,可以看到控制台打印的Request日志信息输出。
|
|
从handlers.LoggingHandler
函数的参数我们可以看出,它接受一个Handler,然后返回一个Handler,其实就是对现有的Handler的一次包装,这就是中间件。
这里的输出参数类型是io.Writer
,所以我们可以输出文件等实现了该接口的任何类型。
Go语言经典库使用分析,未完待续,欢迎扫码关注公众号
flysnow_org
或者网站http://www.flysnow.org/,第一时间看后续系列。觉得有帮助的话,顺手分享到朋友圈吧,感谢支持。
CombinedLoggingHandler
还有一种日志格式,这种日志格式输出的日志信息更详细,更全面,比如包含UA等信息,这种格式被称为Apache Combined Log Format。
CombinedLoggingHandler就是为我们提供输出一种这种格式的中间件,使用方式和LoggingHandler一样。
|
|
看下这个中间件输出的日志信息
|
|
UA+HOST,日志信息更全面了。
CompressHandler
这是一个压缩response的中间件,支持gzip和deflate压缩。如果客户端的请求头里包含Accept-Encoding
,并且值为gzip或者deflate,该中间件就会压缩返回的response,这样就可以减少response的大小,减少响应的时间,使用访问也很简单,这里简单举个例子。
|
|
这里尤其注意的是我们返回的response的内容类型要特别指定一下,不然就会被自动解析为gzip,就变成下载一个gz文件了。我这里强制指定文本类型,这样就可以看到返回的内容Hello World
。
该中间件还有一个函数CompressHandlerLevel可以指定压缩的级别,级别是gzip.BestSpeed和gzip.BestCompression之间的值,如果大家不想用默认压缩级别,可以使用这个函数指定。
还记得Nginx可以开启Gzip加速吧,差不多也是这么个实现。
ContentTypeHandler
这也是一个很有意思的中间件,他的作用是只处理支持的内容类型,如果不支持,则返回415状态码。该中间件只对PUT,POST,PATCH方法有效,其他方法则不做处理,也就相当于没有使用这个中间件。
|
|
最后一个参数是可变参数,我们可以指定多个ContextType类型,这些类型是被我们支持的,其他类型则不支持。如果我们使用PUT、POST、PATCH方法提交的请求的内容类型不在我们支持的内容类型范围内,则返回415错误。
CanonicalHost
这是一个重定向的中间件,他可以把一个Request请求重新定向到另外一个域名上,并且会带上原请求的Path和Query。
|
|
上面的示例,当我们在浏览器内输入http://localhost:1234/flysnow
的访问的时候,会自动跳转到http://www.flysnow.org/flysnow
。
小结
其他的一些不常用的中间的使用方式也类似,大家可以自己看下文档测试下。Go Http的中间件,有点类似于HTTP的拦截器,通过一层层的包装,我们可以组成一个中间件的处理链,便于我们处理我们需要处理的通用性问题,如果哪个中间件不想要,去掉即可,不用对业务代码做任何修改。
例子中的演示,都是一个url对应一个中间件的处理,这个主要是为了演示方面。如果我们相对所有的请求都使用某个中间件怎么做呢?肯定不能使用我们例子中的方式了,因为这样会写很多个。
对于以上这种方式,我们可以借助HTTP Mux路由,因为一个路由也是一个Handler,只用对这个路由应用中间件,就可以拦截处理所有的请求了。
下一篇开始分享这些常用中间件的实现原理和源代码的分析。
Go语言经典库使用分析,未完待续,欢迎扫码关注公众号
flysnow_org
或者网站http://www.flysnow.org/,第一时间看后续系列。觉得有帮助的话,顺手分享到朋友圈吧,感谢支持。
有疑问加站长微信联系(非本文作者)