前言
Ginmartinihttprouter
Gin
32K+
安装
Gin简单示例
request&response Header
vue设置请求头中的token
Gin获取请求头中的Token
Gin响应头设置Token
Gin request
我们可以通过gin的context获取到客户端请求携带的url参数、form表单、json数据、文件等。
Gin shouldBind
默认情况下,我们需要根据客户端请求的content-type,在后端使用不同的方式,获取客户端请求参数。
获取个请求参还需要c.Query、c.PostForm、c.Bind、C.Param,这也太麻烦了~
shouldBind可帮助我们根据客户端request的content-type,自动获取请求参数,并赋值给后端struct的字段。
Gin response
我们web开发过程中,大型项目会采用MVVM(前后端分离)的架构,小型项目会采用MTV(模板渲染)的架构。
疏通同归其目的都是完成数据驱动视图,不同的是数据驱动视图的地方不一样。
貌似web开发玩得就是这6个字,数据----》 驱动-----》视图。空谈误国,怎么才能更好的驱动视图才是关键。
MTV模式(模板渲染):后端使用模板语法也就是字符串替换的方式,在后端直接完成数据和HTML的渲染,直接返回给客户端。
MVVM(前后端分离架构):后端返回json数据,前端使用axios/ajax的方式获取到数据,使用vue等前端框架完成数据到HTML的渲染。
1.RESTful API
只要API程序遵循了REST风格,那就可以称其为RESTful API。
其实核心思想是1个资源对应1个URL,客户端对这1资源操作时(不同的request.get/post/put/delete方法)对应后端的增/删/改/查操作。
例如,我们现在要编写一个管理书籍的系统,我们可以查询对一本书进行查询、创建、更新和删除等操作。
我们在编写程序的时候就要设计客户端浏览器与我们Web服务端交互的方式和路径。按照经验我们通常会设计成如下模式:
| 请求方法 | URL | 含义 |
|---|---|---|
| GET | /book | 查询书籍信息 |
| POST | /create_book | 创建书籍记录 |
| POST | /update_book | 更新书籍信息 |
| POST | /delete_book | 删除书籍信息 |
我们按照RESTful API设计如下:
| 请求方法 | URL | 含义 |
|---|---|---|
| GET | /book | 查询书籍信息 |
| POST | /book | 创建书籍记录 |
| PUT | /book | 更新书籍信息 |
| DELETE | /book | 删除书籍信息 |
c.JSON响应json数据
2.MVC模板渲染
如果是小型项目、历史原因、SEO优化我们使用模板渲染,Gin也是支持MTV模式的。
3.文件上传
http请求也可以传输文件,有时候我们可以使用gin搭建1个ftp服务器。
单个文件上传
多个文件上传
Gin模板渲染
现在大部分都是前后端分离的架构,除了seo优化我们基本不会使用gin做模板渲染。
1.扩展gin模板函数
模板
2.加载静态文件路径
模板
3.Gin模板继承
html/template实现了模板的嵌套和继承,但是gin不包含此功能。但是我们使用第第三方包。github.com/gin-contrib/multitemplate
Gin 路由组
URL路由太多了就需要分组管理,类似Flask的蓝图、Django里面的include URL。这些都是基于反射实现的。
但是Gin框架中的路由使用的是httprouter这个库,其基本原理就是构造一个路由地址的前缀树。
1.单支路由
2.路由组
3.路由嵌套
虽然gin的路由支持嵌套,但是出于对查询性能的考虑我们一般都会不会嵌套很多层路由。
Gin中间件
我们可以在不修改视图函数的前提下,利用Web框架中携带的钩子函数也就是中间件 做权限控制、登录认证、权限校验、数据分页、记录日志、耗时统计.........
注意我们的中间件不仅可以设置1个,也根据我们的业务逻辑设置N个,相当于对用户请求增加了多层过滤。
就像Python里面的多层装饰器。
1.中间件执行流程
由于http请求包含request、response 2个动作所以中间件是双行线,中间件的执行流程就像1个递归函数的执行过程。
2.控制中间件执行流程
所为的控制流程我感觉就是设计中间件这个栈里面包含的层层栈针。
我们在弹匣里装了什么样的子弹,扣动扳机时就会发射出什么子弹,这样想会更简单一些否则很容易被绕进去。
在中间件执行的过程中我们可以控制进栈和出栈流程。
以上代码执行结果:
调用context.Next(),继续调用下一个视图函数进行压栈。(子弹装满弹匣)
调用context.Abort() 阻止继续调用后续的函数,执行完当前栈针(函数)之后出栈。(1发子弹就够了)
调用context.Abort() + return,当前位置返回,当前位置之后的代码都不需要不执行了。(1发哑弹)
3.给单个路由(url)设置中间件
当我们需要对特定的视图函数增加新功能时,可以给它增加1个中间件。
4.全局注册中间件
如果我们需要每个视图函数都设置1个中间件,把这一中间件写到每个视图函数前面会非常不方便,我们可以使用use进行全局注册。
输出:
验证web框架里中间件设计思想是的递归思想。
5.路由组注册中间件
给路由组注册中间件有2种写法
写法1:
写法2:
6.闭包的中间件
以上我们得知:Gin的中间件是以1种gin.HandlerFunc类型存在,在路由和路由组里进行注册。
那我们可以使用闭包将1个开关参数和这个handlerFunc一起包起来。实现对中间进行开关控制比较灵活。
7.夸中间件进行传值
中间件可以有多层,假如我们上游的中间得出的值,如何传递到下游中间件呢?。通过上下文content。
handlergoroutinec.Copy()
8.gin默认中间件
gin.Defaut生成的路由引擎,默认使用了Logger(), Recovery()的中间件。
Logger:用于记录日志
Recovery:用于保证在gin 发生错误时进程不会终止。
Gin设置cookie
1.cookie是server端保存在browser中的用户信息
2.每客户端次访问server端时都会携带该域下的cooki信息到server端。
3.不同域名之间的cookie是不共享的。(无法跨域,所以前后端分离的项目只能使用token)