前言

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)