走进HTTP协议-前置知识-gin框架入门
本文适用人群:了解go语言基础语法,但对go web知识仅是了解的小白选手
如果您已经使用gin开发过相关应用了,此文不适合您,请勿浪费您宝贵的时间往下阅读。
实操写的非常非常详细。如果你看不明白,在评论区反馈或者到下方github仓库提交issue,我来帮你解决问题。
本文所有案例代码都可以在这里获取: MoFishXiaodui/ExecutableManual: 青训营后端-可执行手册-非常详细的手把手教学教程 (github.com)
参考文档
- 介绍 | Gin Web Framework (gin-gonic.com)
- 青训营同学配套课件:HTTP 框架修炼之道 .pptx - 飞书云文档 (feishu.cn)
- 青训营同学配套资料【Go 语言框架与实现 学习资料】字节跳动青训营 - 后端专场 - 掘金 (juejin.cn)
案例4-1创建一个gin服务
这部分ppt没有讲,这里先做这个服务,为下一个案例做准备
-
新建文件夹
4-1gin,作为项目根目录 -
根目录上运行
go mod init ginServer -
运行
go get -u github.com/gin-gonic/gin加载包 -
在根目录创建
main.go -
在main.go中写入
package main import "github.com/gin-gonic/gin" func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) r.Run() // 监听并在 0.0.0.0:8080 上启动服务 } -
直接运行
-
到浏览器查看
localhost:8080/ping的结果,若能看到{"message":"pong"}则说明服务启动成功
案例4-2发送报文
本次案例采用telnet发送报文作为测试
-
启动案例4-1的gin服务
-
cmd运行
telnet localhost 8080,会显示出
2. 如果telnet没有安装,需要自行安装,参考下文附录Windows安装telnet
-
如果如前面所示显示会话框等待输入,那么可以进行一下操作:
-
首先按下快捷键
ctrl+]打开回显,然后再按回车回到会话框。如果你没有开回显的话,你在会话框输入的内容会直接传到服务器上,但没有显示出来,你不能确定自己输入了什么 -
接下来输入以下语句,注意,不要敲错,不支持BackSpace键删除,你输入的每一个字符都是会马上传到服务器
GET /ping HTTP/1.1 host: localhost 输入完指令敲两个回车(第一次的回车是为了标识分开headers信息和body信息,第二次回车就结束报文了)
-
然后可以看到gin服务传回来的json数据
GET /ping HTTP/1.1 host: localhost HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Fri, 11 Aug 2023 03:29:20 GMT Content-Length: 18 {"message":"pong"}
案例4-3发送post报文
-
复制案例4-1的文件夹,改名为4-3postGin
-
在main.go中新增一个post请求的处理方法
r.POST("/sis", func(c *gin.Context) { c.Data(200, "text/plain; charset=utf-8", []byte("ok")) }) -
直接运行
-
cmd执行
telnet localhost 8080进入会话框,关闭回显,发送报文如下POST /sis HTTP/1.1 host: 127.0.0.1 -
测试结果
POST /sis HTTP/1.1 # 请求行 host: 127.0.0.1 # 请求头部 host HTTP/1.1 200 OK # 响应行 Content-Type: text/plain; charset=utf-8 # 响应头部 内容/文件类型 Date: Fri, 11 Aug 2023 04:02:53 GMT # 响应头部 响应时间 Content-Length: 2 # 响应头部 主体长度 ok # 响应主体
案例4-4使用postman发送报文
这个案例主要是体验使用postman发送请求。
- 继续使用4-3的gin服务
- 下载postman,地址:Download Postman | Get Started for Free
- 安装、注册、登录
- 点击Collection、Create new colletion
- 自定义改名
- 点击 Add Request
- 如图填写,点击发送,查看响应即可
HTTP分层设计
为了方便后续学习理解,请认真阅读下面两张图片
案例4-5中间件之不是中间件版
此次案例将在gin返回给客户端数据的前后在控制台打印相关的提示信息,模拟前置和后置操作
-
复制案例4-3文件夹,命名为4-5preAndPost。或者你也可以重新建一个gin项目,并不复杂。
-
main中的代码改为:
r := gin.Default() r.POST("/login", func(c *gin.Context) { // 前置处理 fmt.Println("login request") c.Data(200, "text/plain; charset=utf-8", []byte("login")) // 后置处理 fmt.Println("login sucess") }) r.POST("/logout", func(c *gin.Context) { // 前置处理 fmt.Println("logout request") c.Data(200, "text/plain; charset=utf-8", []byte("logout")) // 后置处理 fmt.Println("logout success") }) r.Run() // 监听并在 0.0.0.0:8080 上启动服务 -
直接运行
-
然后在postman分别进行post测试
-
可以看到控制台有以下输出
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080 login request login sucess [GIN] 2023/08/11 - 16:33:06 | 200 | 1.0411ms | ::1 | POST "/login" logout request logout success [GIN] 2023/08/11 - 16:33:09 | 200 | 488.1µs | ::1 | POST "/logout"
案例4-6中间件
案例4-5中处理两个请求时,前置和后置操作都是一样的,我们可以把这写操作剥离出来,用中间件的方式替换
-
复制案例4-5文件夹,重命名为
4-6middleware -
修改 main.go 代码为
r := gin.Default() // 使用中间件 r.Use(func(c *gin.Context) { fmt.Println("middleware start", c.Request.URL) c.Next() fmt.Println("middleware over") }) r.POST("/login", func(c *gin.Context) { fmt.Println("在login处理函数") c.Data(200, "text/plain; charset=utf-8", []byte("login")) }) r.POST("/logout", func(c *gin.Context) { fmt.Println("在logout处理函数") c.Data(200, "text/plain; charset=utf-8", []byte("logout")) }) r.Run() // 监听并在 0.0.0.0:8080 上启动服务 -
postman发送/login和/logout请求
-
查看控制台输出
(base) PS D:\code\MoFishXiaodui\ExecutableManual\src\4-6middleware> go run . [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details. [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080 middleware start /login 在login处理函数 middleware over [GIN] 2023/08/11 - 16:52:42 | 200 | 0s | ::1 | POST "/login" middleware start /logout 在logout处理函数 middleware over [GIN] 2023/08/11 - 16:52:47 | 200 | 587µs | ::1 | POST "/logout" -
可以验证,之前的post请求处理函数 都是在中间件函数的next()函数执行时触发的
-
测试,如果把Next()函数注释,可以得到以下结果
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080 middleware start /login middleware over 在login处理函数 [GIN] 2023/08/11 - 17:03:07 | 200 | 513µs | ::1 | POST "/login" middleware start /logout middleware over 在logout处理函数 [GIN] 2023/08/11 - 17:03:14 | 200 | 237.7µs | ::1 | POST "/logout"中间件函数会被完整执行,然后再处理后续的post请求函数。
-
了解gin框架中更多的中间件知识 使用中间件 | Gin Web Framework (gin-gonic.com)
案例4-7路由
这里借GPT来解释什么是路由:
问:在后端开发中,路由是什么意思
ChatGPT:
在后端开发中,"路由"(Route)是指将传入的HTTP请求映射到相应的处理程序或处理逻辑的过程。在Web应用程序中,客户端(通常是浏览器)发起HTTP请求,服务器端需要决定如何处理这些请求以返回适当的响应。
路由通常是通过URL来确定的,URL是一个标识资源位置的字符串。在后端开发中,路由机制负责将不同的URL路径映射到不同的处理函数、控制器或方法,从而实现对请求的分发和处理。
例如,在一个Web应用程序中,可能有以下几个路由:
/home: 映射到显示首页的处理函数。/products: 映射到显示产品列表的处理函数。/contact: 映射到显示联系页面的处理函数。当客户端发起一个HTTP请求时,服务器会根据请求的URL路径来选择适当的路由,然后执行与该路由关联的处理逻辑。这可以包括从数据库获取数据、进行业务逻辑处理,最终生成响应内容并将其发送回给客户端。
在不同的后端框架中,路由的实现方式可能会有所不同,但核心思想是将URL映射到代码中的特定处理逻辑。路由是构建Web应用程序的重要组成部分,它使得应用程序能够根据不同的URL路径提供不同的功能和内容。
实际上,在案例4-5和案例4-6已经用到了路由,读者仅需到路由参数 | Gin Web Framework (gin-gonic.com)尝试案例代码熟悉路由和路由参数即可。
附录
Windows安装telnet
-
在设置查看telnet
-
选择
启用或关闭Windows功能 -
在列表勾选
Telnet客户端,点击确定,等待安装完毕 -
此时在cmd运行
telnet可以看到 如下内容,说明telnet启动成功欢迎使用 Microsoft Telnet Client
Escape 字符为 'CTRL+]'
Microsoft Telnet>