gin处理url变量
提出
goodsGroup := router.Group("/goods")
{
goodsGroup.GET("/list", goodlist)
goodsGroup.GET("/1", goodadetail)
goodsGroup.POST("add", creatgoods)
}
其中 goodsGroup.GET("/1", goodadetail)
这样获取id为1的商品并不科学。
goodsGroup := router.Group("/goods")
{
goodsGroup.GET("/list", goodlist)
goodsGroup.GET("/:id/:action", goodadetail) //改成这样的变量
goodsGroup.POST("add", creatgoods)
}
解决
这样可以把url的id放在变量里面 :id
的位置,用于函数处理。在这里函数是goodadetail
。
下面改函数。
func goodadetail(context *gin.Context) {
id := context.Param("id")
action := context.Param("action")
context.JSON(http.StatusOK, gin.H{
"id": id,
"action":action,
})
}
id := context.Param("id")
这是取出url中id的位置放到新创建的id
变量里面。
⚠️这样直接开始会有问题
goodsGroup.GET("/list", goodlist)
goodsGroup.GET("/:id", goodadetail)
显然list的匹配模式和id匹配模式冲突。
改成
goodsGroup.GET("", goodlist) //直接get
goodsGroup.GET("/:id", goodadetail)
goodsGroup.POST("", creatgoods) //直接post
这样比较符合规范。
另外有一种 *
的匹配模式,慎用
goodsGroup.GET("/:id/*action", goodadetail)
如果访问/goods/1/delete/other
在*
模式下会获取到 action:"/delete/other"
就是把后面的东西全部放进去
:
模式下,如果访问/goods/1/delete/another
等只会得到404"
,要完成匹配必须访问类似 /goods/1/delete/other
。。可能说不清楚。简而言之:
下匹配更加强制格式,*
则更像对路径的一把抓。
*
模式一般用于获取文件路径等情况。动态url,比如id之类还是用:
。
约束url
goodsGroup.GET("/list", goodlist)
goodsGroup.GET("/:id/:action", goodadetail)
会把list当id,需要约束,比如非数字的404处理。
下面是写的例子
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
type Person struct {
ID string `uri:"id" binding:"required,uuid"` //ID必须string类型,required表示必须,格式是uuid类型
Name string `uri:"name" binding:"required"`
}
func main() {
rooter := gin.Default()
rooter.GET("/:name/:id", func(context *gin.Context) {
var person Person
//err取值为匹配后的错误 &person传入函数的地址。 err != nil就是有错
if err := context.ShouldBindUri(&person); err != nil {
context.Status(404)
return //直接return,否则出错了还要执行下面的逻辑
}
context.JSON(http.StatusOK,gin.H{
"name":person.Name,
"id":person.ID,
})
})
rooter.Run(":8083")
}
主要是定义 Person结构体,用于匹配url里面的传值类型。
然后分别对传值无误和有误的数据进行处理
其中表单验证之后在写。