0


【Go语言】Gin 框架教程

Gin 框架教程

1.第一个 Gin 程序

1.1 Gin 安装

  1. # 执行执行如下操作即可,安装Gin前需要安装Go环境
  2. go get -u-v github.com/gin-gonic/gin
  3. # -v:打印出被构建的代码包的名字# -u:已存在相关的代码包,强行更新代码包及其依赖包

1.2 Gin 项目创建

在一个空文件夹里新建文件

  1. main.go

,参考如下代码编写一个

  1. Gin

程序。

  1. // blog.euansu.cn// main.gopackage main
  2. import"github.com/gin-gonic/gin"funcmain(){
  3. r := gin.Default()
  4. r.GET("/",func(c *gin.Context){
  5. c.String(200,"Hello, EuanSu")})
  6. r.Run()// listen and serve on 0.0.0.0:8080}

运行

  1. main.go

程序,如下图所示。

  1. go run main.go

在这里插入图片描述

代码说明:

  1. 首先,r := gin.Default()这里生成了一个 Gin 引擎实例,用于处理 HTTP 请求,也即 WSGI 应用程序,这个实例会预先加载一些默认的中间件。
  2. r.GET("/", ...) 则是声明了一个路由,以及路由对应的函数方法。
  3. r.Run() 函数则是运行应用程序,默认的监听端口是 8080,也可以传入参数设置应用程序运行端口,例如 r.Run(":8888"),即应用运行在 8888 端口。

1.3 网站图标设置

这里使用一个

  1. Gin

的中间件

  1. github.com/thinkerou/favicon

,使用同

  1. gin

框架,首先是安装

  1. github.com/thinkerou/favicon

库。

  1. go get github.com/thinkerou/favicon

接下来,则是使用该中间件,代码如下所示:

  1. // blog.euansu.cn// main.gopackage main
  2. import("github.com/gin-gonic/gin""github.com/thinkerou/favicon")funcmain(){// 创建一个服务
  3. r := gin.Default()// 使用中间件
  4. r.Use(favicon.New("./static/favicon.ico"))// 路由函数
  5. r.GET("/",func(c *gin.Context){
  6. c.String(200,"Hello, EuanSu")})
  7. r.Run()// listen and serve on 0.0.0.0:8080}

项目运行后,就能够在浏览器中看到

  1. favicon.ico

网站图标。

在这里插入图片描述

2.Gin 中的路由

2.1 路由语法

  1. $router.$method("$router", $handlerFunction)
  2. # router,Gin 引擎实例
  3. # method,http路由方法,可选参数为:GET、POST、PUT、PATCH、DELETE、OPTIONS、HEAD以及能够处理任意类型的HTTP请求的Any和处理指定类型的HTTP请求的Match
  4. # handlerFunction,路由函数,处理路由响应

示例如下:

  1. router.GET("/path", handlerFunction)// 获取资源
  2. router.POST("/path", handlerFunction)// 创建资源
  3. router.PUT("/path", handlerFunction)// 更新资源
  4. router.DELETE("/path", handlerFunction)// 删除资源
  5. router.PATCH("/path", handlerFunction)// 更新部分资源
  6. router.OPTIONS("/path", handlerFunction)// 获取服务器支持的 HTTP 方法
  7. router.HEAD("/path", handlerFunction)// 获取资源的头部信息
  8. router.Any("/path", handlerFunction)// 处理任意类型的 HTTP 请求
  9. router.Match([]string{"GET","POST"},"/path", handlerFunction)// 处理指定类型的 HTTP 请求

2.2 请求参数的处理

2.2.1 路由参数解析

参数包含在路由中,如

  1. /user/:name

,通过调用不同的

  1. 路由参数

传入不同的

  1. name

,如下所示:

  1. r.GET("/user/:name",func(c *gin.Context){
  2. name := c.Param("name")
  3. c.String(http.StatusOK,"%s, Welcome to your clicl.", name)})

在这里插入图片描述

这里需要注意下,如果新增了路由,需要重启

  1. Gin

程序,重启之后,再次访问路由地址,就能够正常解析路由参数了。

在这里插入图片描述

2.2.2 Query 参数解析
  1. Query 参数

与上文的路由参数一样,参数都是路由的一部分,不同的是

  1. Query 参数

是键值对的形式,查询参数通常位于URL的问号(

  1. ?

)之后,以键值对的形式出现,并且多个参数之间用与号(

  1. &

)分隔。

  1. r.GET("/users",func(c *gin.Context){
  2. name := c.Query("name")
  3. c.String(http.StatusOK,"%s, Thank you for your click.", name)})

在这里插入图片描述

也可以直接使用

  1. URL

通过浏览器请求该接口。

在这里插入图片描述

2.2.3 POST 参数解析(form表单)

这里使用一个表单参数进行举例,如下所示,输入分数转化为及格、不及格的判断,代码如下所示。

  1. package main
  2. import("github.com/gin-gonic/gin""net/http""strconv")funcevaluateScore(score int)string{if score >=90{return"优秀"}elseif score >=60{return"及格"}else{return"不及格"}}funcmain(){
  3. r := gin.Default()// POST参数解析// POST
  4. r.POST("/form",func(c *gin.Context){
  5. username := c.PostForm("username")// DefaultPostForm,只支持string类型,因此需要进行类型的转换
  6. scoreStr := c.DefaultPostForm("score","0")
  7. score, err := strconv.Atoi(scoreStr)if err !=nil{// 处理错误情况,例如当输入的值不是整数时
  8. c.JSON(http.StatusBadRequest, gin.H{"error":"Invalid score"})return}
  9. result :=evaluateScore(score)
  10. c.JSON(http.StatusOK, gin.H{"username": username,"score": score,"evaluation": result})})
  11. r.Run()// listen and serve on 0.0.0.0:8080}
  12. r.POST("/form",func(c *gin.Context){
  13. username := c.PostForm("username")
  14. password := c.DefaultPostForm("password","000000")// 可设置默认值
  15. fmt.Println(password)
  16. c.String(http.StatusOK,"%s, Thank you for your login.", username)})

请求后端的接口,返回如下。

在这里插入图片描述

2.2.4 POST 参数解析(json)
  1. package main
  2. import("github.com/gin-gonic/gin""net/http""strconv")funcevaluateScore(score int)string{if score >=90{return"优秀"}elseif score >=60{return"及格"}else{return"不及格"}}// 定义结构体,与JSON数据匹配type Person struct{
  3. Username string`json:"username"`
  4. Score int`json:"score"`}funcmain(){
  5. r := gin.Default()// 处理POST请求,接收JSON参数
  6. r.POST("/json",func(c *gin.Context){var person Person
  7. // 绑定JSON到结构体if err := c.ShouldBindJSON(&person); err !=nil{
  8. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}
  9. result :=evaluateScore(person.Score)
  10. c.JSON(http.StatusOK, gin.H{"username": person.Username,"score": person.Score,"evaluation": result})})
  11. r.Run()// listen and serve on 0.0.0.0:8080}

请求后端的接口,返回如下。

在这里插入图片描述

2.3 路由处理

2.3.1 重定向
  1. r.GET("/redirect",func(c *gin.Context){
  2. c.Redirect(http.StatusMovedPermanently,"/")})

如下所示,当后端收到

  1. /redirect

路由的请求,会重定向至

  1. /

在这里插入图片描述

2.3.2 分组路由

分组路由主要是为了处理路由前缀一致的情况,例如有一组路由前缀都是

  1. /api/v1

开头,通过分组路由就能够简化路由的定义,也可以更好的实现路由的权限控制,例如将需要登录的路由放到同一分组中。代码示例如下:

  1. // 默认的路由方法
  2. defaultHandler :=func(c *gin.Context){
  3. c.JSON(http.StatusOK, gin.H{"path": c.FullPath(),})}// group: v1
  4. v1 := r.Group("/v1"){
  5. v1.GET("/posts", defaultHandler)
  6. v1.GET("/series", defaultHandler)}// group: v2
  7. v2 := r.Group("/v2"){
  8. v2.GET("/posts", defaultHandler)
  9. v2.GET("/series", defaultHandler)}

请求不同的路由地址,均能够得到正常的响应。

在这里插入图片描述

在这里插入图片描述

3.RESTful API

  1. RESTful API

具体概念可以查看

  1. https://blog.euansu.cn/post/djangorestframework/

这篇文章中关于

  1. RESTful API

的相关介绍 。

使用

  1. Go

语言能够快速的实现

  1. RESTful API

,实现如下:

  1. r.GET("/user",func(c *gin.Context){
  2. c.JSON(http.StatusOK, gin.H{"msg":"get user"})})
  3. r.POST("/user",func(c *gin.Context){
  4. c.JSON(http.StatusOK, gin.H{"msg":"post user"})})
  5. r.PUT("/user",func(c *gin.Context){
  6. c.JSON(http.StatusOK, gin.H{"msg":"put user"})})
  7. r.DELETE("/user",func(c *gin.Context){
  8. c.JSON(http.StatusOK, gin.H{"msg":"delete user"})})

使用

  1. Apifox

等接口测试工具测试,应用程序能够根据使用的

  1. HTTP

请求方式的不同而使用不同的函数进行处理。

  • GET 请求在这里插入图片描述
  • POST 请求在这里插入图片描述
  • PUT 请求在这里插入图片描述
  • DELETE 请求在这里插入图片描述

如上测试所示,

  1. Gin

框架能够快速、简洁的实现

  1. RESTful API

4.响应页面

可以通过以下方式,先加载静态页面到

  1. Gin

应用程序中。

  1. // 加载静态页面
  2. r.LoadHTMLGlob("templates/*")// 加载指定的静态页面(不推荐)
  3. r.LoadHTMLFiles("templates/index.html")

路由函数

  1. r.GET("/",func(c *gin.Context){
  2. c.HTML(http.StatusOK,"index.html", gin.H{"msg":"index.html","path":"/"})})

打开浏览器,访问

  1. Gin

  1. /

路由,显示如下。

在这里插入图片描述

5.中间件

首先是在项目中,声明一个中间件方法

  1. myHandler()

,如下是

  1. myHandler()

的代码方法。

  1. funcmyHandler() gin.HandlerFunc {returnfunc(c *gin.Context){// 设置中间件的值
  2. c.Set("usersession","xxx")if c.Request.URL.Path =="/"{// 阻止
  3. fmt.Println("阻止")
  4. c.Abort()}// 放行
  5. fmt.Println("放行")
  6. c.Next()}}

  1. Gin

应用程序中使用这个中间件。

  1. funcmain(){// 创建一个服务
  2. r := gin.Default()// 使用中间件
  3. r.Use(myHandler())...
  4. r.Run()// listen and serve on 0.0.0.0:8080}

实际测试效果如下:

  • 请求 / 路由,后端返回为空。在这里插入图片描述
  • 请求其他的路由,则不受影响,就如我们在中间件方法所写的判断一样,仅仅只是拦截了 / 的路由请求。在这里插入图片描述

6.数据库

  1. Gin

项目中使用数据库,涉及以下操作:

  1. 安装数据库驱动和 ORM 库,安详需要使用的数据库驱动和 ORM 库,常见的 ORM 库是 GORM,支持 MySQLPostgreSQLSQLite 等数据库。
  2. 配置数据库的连接信息,需要在 Gin 项目配置中配置数据库连接,通常是 main.go 或者单独的配置文件。
  3. 初始化数据库,在项目启动的时候,进行数据库连接的初始化。
  4. 项目中使用数据库, 在路由关联的函数中使用数据进行增删改查的操作。

6.1 安装数据库驱动和 ORM 库

  1. go get -u gorm.io/gorm
  2. go get -u gorm.io/driver/mysql

6.2 配置数据库的连接信息

  1. main.go

文件中配置数据库的连接信息。

  1. // 数据库连接信息
  2. dsn :="username:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"var err error// 连接数据库
  3. db, err = gorm.Open(mysql.Open(dsn),&gorm.Config{})if err !=nil{
  4. log.Fatalf("无法连接数据库: %v", err)}

6.3 数据库初始化

使用

  1. gorm

库,定义数据库模型,在

  1. main.go

文件中添加

  1. AutoMigrate

方法,进行数据库的迁移操作。

  1. // 定义一个全局的数据库连接变量var db *gorm.DB
  2. // User 定义数据库模型type User struct{
  3. ID uint`json:"id" gorm:"primaryKey"`
  4. Username string`json:"username"`
  5. Email string`json:"email"`}funcmain(){// 创建一个服务
  6. r := gin.Default()// 使用中间件
  7. r.Use(favicon.New("./static/favicon.ico"))
  8. r.Use(myHandler())// 加载静态页面
  9. r.LoadHTMLGlob("templates/*")// 数据库连接信息
  10. dsn :="username:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"var err error// 连接数据库
  11. db, err = gorm.Open(mysql.Open(dsn),&gorm.Config{})if err !=nil{
  12. log.Fatalf("无法连接数据库: %v", err)}// 自动迁移数据库
  13. db.AutoMigrate(&User{})
  14. r.Run()// listen and serve on 0.0.0.0:8080}

项目启动如下,项目启动后,执行

  1. AutoMigrate

方法。

在这里插入图片描述

连接配置的数据库,发现

  1. AutoMigrate

初始化生成的表,数据库迁移操作成功。

在这里插入图片描述

6.4 数据库使用

如下是获取用户列表和创建用户的两个函数方法。

  1. // 获取用户列表的处理函数funcgetUsers(c *gin.Context){var users []User
  2. result := db.Find(&users)if result.Error !=nil{
  3. c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})return}
  4. c.JSON(http.StatusOK, users)}// 创建用户的处理函数funccreateUser(c *gin.Context){var user User
  5. if err := c.ShouldBindJSON(&user); err !=nil{
  6. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}
  7. result := db.Create(&user)if result.Error !=nil{
  8. c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})return}
  9. c.JSON(http.StatusOK, user)}

  1. main.go

中添加路由函数,如下所示:

  1. // 定义路由和处理函数
  2. r.GET("/users", getUsers)
  3. r.POST("/users", createUser)

进行路由请求,如下所示:

  • POST 请求进行用户的创建。在这里插入图片描述
  • GET 请求获取用户信息。在这里插入图片描述

数据库操作的完整代码为:

  1. // blog.euansu.cn// main.gopackage main
  2. import("fmt""github.com/gin-gonic/gin""github.com/thinkerou/favicon""gorm.io/driver/mysql""gorm.io/gorm""log""net/http")funcmyHandler() gin.HandlerFunc {returnfunc(c *gin.Context){// 设置中间件的值
  3. c.Set("usersession","xxx")if c.Request.URL.Path =="/"{// 阻止
  4. fmt.Println("阻止")
  5. c.Abort()}// 放行
  6. fmt.Println("放行")
  7. c.Next()}}// 定义一个全局的数据库连接变量var db *gorm.DB
  8. // User 定义数据库模型type User struct{
  9. ID uint`json:"id" gorm:"primaryKey"`
  10. Username string`json:"username"`
  11. Email string`json:"email"`}funcmain(){// 创建一个服务
  12. r := gin.Default()// 使用中间件
  13. r.Use(favicon.New("./static/favicon.ico"))
  14. r.Use(myHandler())// 加载静态页面
  15. r.LoadHTMLGlob("templates/*")// 数据库连接信息
  16. dsn :="username:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"var err error// 连接数据库
  17. db, err = gorm.Open(mysql.Open(dsn),&gorm.Config{})if err !=nil{
  18. log.Fatalf("无法连接数据库: %v", err)}// 自动迁移数据库
  19. db.AutoMigrate(&User{})// 定义路由和处理函数
  20. r.GET("/users", getUsers)
  21. r.POST("/users", createUser)// 路由函数
  22. r.GET("/",func(c *gin.Context){//c.String(200, "Hello, EuanSu")
  23. c.HTML(http.StatusOK,"index.html", gin.H{"msg":"index.html","path":"/"})})
  24. r.GET("/home",func(c *gin.Context){//c.String(200, "Hello, EuanSu")
  25. c.HTML(http.StatusOK,"index.html", gin.H{"msg":"index.html","path":"/home"})})
  26. r.Run()// listen and serve on 0.0.0.0:8080}funcgetUsers(c *gin.Context){var users []User
  27. result := db.Find(&users)if result.Error !=nil{
  28. c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})return}
  29. c.JSON(http.StatusOK, users)}funccreateUser(c *gin.Context){var user User
  30. if err := c.ShouldBindJSON(&user); err !=nil{
  31. c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}
  32. result := db.Create(&user)if result.Error !=nil{
  33. c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})return}
  34. c.JSON(http.StatusOK, user)}

7.相关链接

[1] Go Gin 简明教程 https://geektutu.com/post/quick-go-gin.html

[2] 【【狂神说】Gin框架一小时上手 | 快速转型GoWeb开发 | Go语言零基础教程】 https://www.bilibili.com/video/BV1Rd4y1C7A1/?share_source=copy_web&vd_source=5fdcc6213ac2d30f16a78fe5d6e8df4d

标签: golang gin

本文转载自: https://blog.csdn.net/suu_an/article/details/139721014
版权归原作者 南歌EuanSu 所有, 如有侵权,请联系我们删除。

“【Go语言】Gin 框架教程”的评论:

还没有评论