0. 前面的话
Web应用程序(Web Application) 是一种通过网络(通常是互联网)访问的软件应用程序。与传统的桌面应用程序不同,Web应用程序运行在Web浏览器中,并通过与远程服务器的交互来提供功能和服务。用户可以通过在浏览器中输入URL或点击链接来访问Web应用程序。
而在 Go 语言中,最常用的 Web 框架便是我们熟知的 Gin 框架,Gin 是一个轻量级的 Web 框架,具有快速的路由和中间件支持。它被设计为高性能且易于使用,适用于构建各种规模的 Web 应用程序。
本篇文章将为大家简单介绍 Gin 框架的基本用法。
1. 简单上手
1.1. 安装与使用
安装 Gin 非常简单,只需要打开终端输入以下指令即可
go get -u github.com/gin-gonic/gin
安装完成后,在后续的使用中,我们只需要导入该包即可
import "github.com/gin-gonic/gin"
1.2. Hello World
按照传统惯例,一段Hello World
是少不了的,我们可建立文件编写下列代码来实现
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World")
})
router.Run(":8090") // 默认监听8080端口
}
使用 Gin 实现 Hello world 非常简单,创建一个路由 router,然后执行 Run 方法即可。
对于上述的代码,我们来简单分析一下代码结构:
- 1、
router := gin.Default()
:这是默认的服务器。使用gin的Default
方法创建一个路由Handler
; - 2、然后通过Http方法绑定路由规则和路由函数。不同于
net/http
库的路由函数,gin进行了封装,把reques
t和response
都封装到了gin.Context
的上下文环境中。 - 3、最后启动路由的Run方法监听端口。还可以用
http.ListenAndServe(":8080", router)
,或者自定义Http服务器配置。
简单几行代码,就能实现一个web服务。使用gin的Default方法创建一个路由handler。然后通过HTTP方法绑定路由规则和路由函数。不同于net/http库的路由函数,gin进行了封装,把request和response都封装到gin.Context的上下文环境。最后是启动路由的Run方法监听端口。麻雀虽小,五脏俱全。
当然,除了GET方法,gin也支持POST、PUT、DELETE、OPTION等常用的restful方法。
2. Restful 路由
2.1. 路由的定义
在 Gin 框架中,路由定义是指将 URL 路径映射到相应的处理函数,以便根据客户端发起的请求来执行特定的操作。Gin 支持常见的 HTTP 请求方法(GET、POST、PUT、DELETE 等),可以根据不同的请求方法来定义相应的路由。
r.GET("/hello", func(c *gin.Context) {
// 处理 GET /hello 请求的代码
})
r.POST("/create", func(c *gin.Context) {
// 处理 POST /create 请求的代码
})
r.PUT("/update/:id", func(c *gin.Context) {
// 处理 PUT /update/:id 请求的代码
})
r.DELETE("/delete/:id", func(c *gin.Context) {
// 处理 DELETE /delete/:id 请求的代码
})
在上述示例中,每个方法的第一个参数是一个字符串,表示要匹配的 URL 路径。当客户端发起对应的 HTTP 请求时,Gin 框架将调用指定的处理函数,这个函数的参数是一个 gin.Context
对象,通过它可以访问请求信息和构建响应。
2.2. 路由参数
Gin 的路由来自 httprouter 库。因此 httprouter 具有的功能, Gin 也具有,不过 Gin 不支持路由正则表达式。
2.2.1. API参数
api 参数通过Context的Param方法来获取。
router.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, name)
})
冒号:
加上一个参数名组成路由参数。可以使用 c.Params 的方法读取其值。当然这个值是字串 string。诸如/user/hanru
,和/user/hello
都可以匹配,而/user/
和/user/hanru/
不会被匹配。
router.GET("/user/:name/*action", func(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, message)
})
2.2.2. URL参数
Web 提供的服务通常是 client 和 server 的交互。其中客户端向服务器发送请求,除了路由参数,其他的参数无非两种,查询字符串 query string 和报文体 body 参数。所谓 Query string,即查询字符串,用 ?
以后连接的 key1 = value2 & key2 = value2
的形式的参数。当然这个 key-value 是经过 urlencode 编码。
URL 参数通过 DefaultQuery 或 Query 方法获取。
对于参数的处理,经常会出现参数不存在的情况,对于是否提供默认值,Gin 也考虑了,并且给出了一个优雅的方案,使用 c.DefaultQuery
方法读取参数,其中当参数不存在的时候,提供一个默认值。使用 Query 方法读取正常参数,当参数不存在的时候,返回空字串。
func main() {
router := gin.Default()
router.GET("/welcome", func(c *gin.Context) {
name := c.DefaultQuery("name", "Guest") //可设置默认值
//nickname := c.Query("nickname") // 是 c.Request.URL.Query().Get("nickname") 的简写
c.String(http.StatusOK, fmt.Sprintf("Hello %s ", name))
})
router.Run(":8090")
}
2.2.3 表单参数
http 的报文体传输数据就比 query string 稍微复杂一点,常见的格式就有四种。
例如application/json
,application/x-www-form-urlencoded
,application/xml
和multipart/form-data
。后面一个主要用于图片上传。
json格式的很好理解,urlencode其实也不难,无非就是把query string的内容,放到了body体里,同样也需要urlencode。
默认情况下,c.PostFROM
解析的是x-www-form-urlencoded
或from-data
的参数。
表单参数通过 PostForm
方法获取:
func main() {
router := gin.Default()
//form
router.POST("/form", func(c *gin.Context) {
type1 := c.DefaultPostForm("type", "alert") //可设置默认值
username := c.PostForm("username")
password := c.PostForm("password")
//hobbys := c.PostFormMap("hobby")
//hobbys := c.QueryArray("hobby")
hobbys := c.PostFormArray("hobby")
c.String(http.StatusOK, fmt.Sprintf("type is %s, username is %s, password is %s,hobby is %v", type1, username, password,hobbys))
})
router.Run(":8090")
}
3. 中间件
中间件的意思就是,对一组接口的统一操作,可以把逻辑提取出来,类似于横切关注点,常用于一些记录 log,错误 handler,还有就是对部分接口的鉴权。
比如有一组 API 接口是用户登入后的操作,我们就需要在进入每个 API 接口前都进行权限的验证。有了中间件后,我们只需要创建一个中间件,权限的验证放到中间件,然后把 这个中间件绑定到那一组 API 上即可。下面就实现一个简易的鉴权中间件。
func AuthMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.Request.Header.Get("Authorization")
authorized := check(token) //调用认证方法
if authorized {
c.Next()
return
}
c.JSON(http.StatusUnauthorized, gin.H{
"error": "Unauthorized",
})
c.Abort()
return
}
}
func main() {
r := gin.Default()
r.GET("/path", AuthMiddleWare(), func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "ok"})
})
}
我们定义了一个 AuthMiddleWare 中间件,中间件的功能是提测请求的头部 Authorization,将获取的 token 调用认证方法判断,是否是合法的 token。在处理器中,增加 AuthMiddleWare() 中间件即可。
4. 小结
总的来说,Gin 是一个轻巧而强大的 Golang Web 框架,路由性能高,在各种 Web 框架中处于领先地位。Gin 框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用。