回顾

上一节我们用Gin框架快速搭建了一个GET请求的接口,今天来学习路由和参数的获取。

请求动词

RESTfulRESTfulPOSTDELETEPUTGET
PATCHOPTIONHEADrentergroup.goIRoutes
type IRoutes interface {
	Use(...HandlerFunc) IRoutes

	Handle(string, string, ...HandlerFunc) IRoutes
	Any(string, ...HandlerFunc) IRoutes
	GET(string, ...HandlerFunc) IRoutes
	POST(string, ...HandlerFunc) IRoutes
	DELETE(string, ...HandlerFunc) IRoutes
	PATCH(string, ...HandlerFunc) IRoutes
	PUT(string, ...HandlerFunc) IRoutes
	OPTIONS(string, ...HandlerFunc) IRoutes
	HEAD(string, ...HandlerFunc) IRoutes

	StaticFile(string, string) IRoutes
	Static(string, string) IRoutes
	StaticFS(string, http.FileSystem) IRoutes
}
RenterGroupIRoutesgin.DefaultEngineRenterGroupgin.Default
func main() {
	router := gin.Default()
	router.POST("/article", func(c *gin.Context) {
		c.String(200, "article post")
	})
	router.DELETE("/article", func(c *gin.Context) {
		c.String(200, "article delete")
	})
	router.PUT("/article", func(c *gin.Context) {
		c.String(200, "article put")
	})
	router.GET("/article", func(c *gin.Context) {
		c.String(200, "article get")
	})
	router.Run()
}

请求动词的第一个参数是请求路径,第二个参数是用于逻辑处理的函数,可以是匿名的或是其他地方定义的函数名。不同的请求动词可以定义相同的路径,只需要切换动词就可以进入对应的处理逻辑。

curl -X PUT http://localhost:8080/article
curl -X POST http://localhost:8080/article
curl -X GET http://localhost:8080/article
curl -X DELETE http://localhost:8080/article

路由参数

?name=pingye/article/1
protocol://hostname:[port]/path/[query]#fragment
1
:id1:idc.Paramid
router.GET("/article/:id", func(c *gin.Context) {
  id := c.Param("id")
  c.String(200, id)
})
:idid404
*id
router.GET("/article/*id", func(c *gin.Context) {
  id := c.Param("id")
  c.String(200, id)
})

普通参数

GET
http://localhost:8080/welcome?firstname=Jane&lastname=Doe
c.Queryc.DefaultQuery
router.GET("/welcome", func(c *gin.Context) {
   firstname := c.DefaultQuery("firstname", "pingyeaa")
   lastname := c.Query("lastname")
   c.String(200, firstname+" "+lastname)
})
GetQueryDefaultQuery
func (c *Context) DefaultQuery(key, defaultValue string) string {
	if value, ok := c.GetQuery(key); ok {
		return value
	}
	return defaultValue
}

func (c *Context) Query(key string) string {
	value, _ := c.GetQuery(key)
	return value
}

表单参数

form
router.POST("/form_post", func(c *gin.Context) {
  message := c.PostForm("message")
  nick := c.DefaultPostForm("nick", "anonymous")

  c.JSON(200, gin.H{
    "status":  "posted",
    "message": message,
    "nick":    nick,
  })
})
curl -d "message=pingye" http://localhost:8080/form_post
{"message":"pingye","nick":"anonymous","status":"posted"}

数组类型参数

name
POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
Content-Type: application/x-www-form-urlencoded
QueryMapmap
router.GET("/post", func(c *gin.Context) {
  ids := c.QueryMap("ids")
  c.String(200, ids["a"]+" "+ids["b"])
})
curl http://localhost:8080/post?ids[a]=pingye&ids[b]=hehe
pingye hehe

文件上传

书到用时方恨少
FormFileFileHeaderFilename
type FileHeader struct {
   Filename string
   Header   textproto.MIMEHeader
   Size     int64

   content []byte
   tmpfile string
}
router.POST("/upload", func(c *gin.Context) {
  file, _ := c.FormFile("file")
  c.String(200, file.Filename)
})
curl
curl -X POST http://localhost:8080/upload 
  -F "file=@/Users/enoch/Downloads/IMG_9216.JPG" 
  -H "Content-Type: multipart/form-data"
IMG_9216.JPG
SaveUploadedFile
router.POST("/upload", func(c *gin.Context) {
		file, _ := c.FormFile("file")
		c.String(200, file.Filename)
		err := c.SaveUploadedFile(file, "/Users/enoch/Desktop/ab.png")
		if err != nil {
			c.String(500, err.Error())
		}
})

路由分组

v1/article
v1 := r.Group("v1")
{
  v1.POST("/login", func(c *gin.Context) {
    c.String(200, "v1/login")
  })
  v1.POST("/submit", func(c *gin.Context) {
    c.String(200, "v1/submit")
  })
}

v2 := r.Group("v2")
{
  v2.POST("/login", func(c *gin.Context) {
    c.String(200, "v2/login")
  })
  v2.POST("/submit", func(c *gin.Context) {
    c.String(200, "v2/submit")
  })
}
curl -X POST http://localhost:8080/v1/login
curl -X POST http://localhost:8080/v2/login

感谢大家的观看,如果觉得文章对你有所帮助,欢迎关注公众号「平也」,聚焦Go语言与技术原理。

  • 还没有人评论,欢迎说说您的想法!