开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
参数
参数作为前端传递到后端的数据,无论在任何的Web框架中都是至关重要需要完全掌握的,在Gin框架中,可以接收多种类型的参数,包括API参数、表单参数以及JSON数据。
API参数
API参数是将参数写到API中的一种参数传递方式,Gin框架可以从API中取出前端传递的参数,例如有一个获取用户信息的接口为 /user/get_user,我们可以把用户ID通过API参数发送给后端,例如 /user/get_user/1001,则表示获取1001这个用户的信息。
在Gin框架中绑定路由时,可以通过冒号(:)或者星号(*)加参数名称的方式形成一个占位符,这样在代码中可以通过*gin.Context
的Param
方法获取到API参数,需要注意的是:使用冒号占位符获取到的参数不包含路径里面的斜杠(/),但是使用星号占位符获取到的参数包含。
示例代码:
func main() {
g := gin.Default()
g.GET("/v1/get_user/:userId", func(c *gin.Context) {
userId := c.Param("userId")
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"userID": userId,
})
})
g.GET("/v2/get_user/*userId", func(c *gin.Context) {
userId := c.Param("userId")
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"userID": userId,
})
})
err := g.Run(":8888")
if err != nil {
return
}
}
运行结果:
URL参数
除了将参数作为URL路径的一种传递方式之外,使用更多的是通过在URL后面加参数进行传递的方法,例如同样的获取用户信息,使用URL可以这样传递参数:/user/get_user?userId=1001。
在Gin框架中可以使用Query方法或者是DefaultQuery方法获取到前端传递的参数。
示例代码:
func main() {
g := gin.Default()
g.GET("/user/get_user", func(c *gin.Context) {
userId := c.Query("userId")
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"userID": userId,
})
})
err := g.Run(":8888")
if err != nil {
return
}
}
运行结果:
注意:Query方法和DefaultQuery方法的区别在于DefaultQuery可以在获取参数时给定一个默认值,当没有从前端获取到参数时,则返回的就是自己设置的默认值。
表单参数
前面介绍的两种都是GET请求的参数传递方式,而表单参数一般都是POST的请求方式,前端通过表单传递的数据Gin框架可以使用PostForm或者DefaultPostForm方法来获取参数,两个方法的区别和上面URL方法获取参数时一样。
示例代码:
func main() {
g := gin.Default()
g.POST("/user/register", func(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
age := c.PostForm("age")
c.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
"age": age,
})
})
err := g.Run(":8888")
if err != nil {
return
}
}
运行结果:
JSON参数
前后端分离项目中,JSON才是参数传递的主力军,同样也是最重要的一种传递方法。
在使用JSON时,Gin框架中可以根据前端传递过来的JSON串将数据绑定到结构体上。
代码示例:
type Person struct {
Name string `json:"name" binding:"required"`
Age int `json:"age" binding:"required"`
}
func main() {
g := gin.Default()
g.POST("/user/register", func(c *gin.Context) {
var person Person
err := c.BindJSON(&person)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "请求参数异常",
})
} else {
c.JSON(http.StatusOK, person)
}
})
err := g.Run(":8888")
if err != nil {
return
}
}
运行结果:
数据绑定详解:
在传递JSON数据进行数据绑定时,需要使用结构体并且配合结构体的json标签使用,例如上面代码中的json标签里面分别都写了有结构体字段对应的名字,前端在传递参数时就需要按照json标签指定的名称进行传递,否则后端接收不到,同时还有binding标签,binding:"required"
表示这个参数是必传的,如果前端不传,则Gin框架会直接报错。(有关于参数校验后面详解)
上面代码绑定JSON串的方法使用的是BindJSON,在Gin框架中还有ShouldBindJSON方法,使用方式和BindJSON一致。区别在于BindJSON在出错时会自动往header中写入400错误码,而ShouldBindJSON不会。
其他数据绑定
除了JSON数据绑定之外,最开始介绍的表单参数、URL参数Gin都可以使用这种数据绑定的方式来获取。
代码示例:
type Person struct {
Name string `form:"name" binding:"required"`
Age int `form:"age" binding:"required"`
}
func main() {
g := gin.Default()
g.POST("/user/register", func(c *gin.Context) {
var person Person
err := c.Bind(&person)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"message": "请求参数异常",
})
} else {
c.JSON(http.StatusOK, person)
}
})
err := g.Run(":8888")
if err != nil {
return
}
}
运行结果:
和JSON绑定的区别:
- 结构体使用form标签
- 使用Bind方法绑定数据
同样的URL参数和Query参数都可以通过数据绑定的方法获取到数据,区别就是结构体的标签和绑定数据的方法不一样。
URL参数
标签:uri
绑定数据方法:BindUri和ShouldBindUri
Query参数:
标签:form
绑定数据方法:BindQuery和ShouldBindQuery