下载使用
$ go get -u github.com/gin-gonic/gin
import "github.com/gin-gonic/gin"
HTTP服务
func main() {
router := gin.Default()
//路由
router.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello gin",
})
})
router.Run(":8080")
}
路由绑定
router.GET("/", index)表示用GET方式接收路由,如果路由是根目录,那么直接执行index控制器方法,index控制器必须含有gin.Context参数,也可以向上面一样将index控制器的内容写成匿名函数。
router.GET("/", index)
func index(c *gin.Context) {
c.JSON(200, gin.H{
"msg": "hello gin",
})
}
路由分离
为了更好的管理路由,最好将路由和控制器分开不同的文件
在根目录下新建router.go
package gin
import (
"github.com/gin-gonic/gin"
"os"
"path/filepath"
)
func initRouter() *gin.Engine {
//路由
router := gin.Default()
router.GET("/", index)
return router
}
在main方法中进行初始化
func main() {
router := initRouter()
router.Run(":8080")
}
此时目录结构如下
--src
--gin
--gin.go #用于存放控制器
--router.go #用于存放路由
--main.go
路由组
一些情况下,我们会有统一前缀的 url 的需求,典型的如 Api 接口版本号 /v1/something。Gin 可以使用 Group 方法统一归类到路由组中
func main() {
router := gin.Default()
// /v1/login 就会匹配到这个组
v1 := router.Group("/v1")
{
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}
// 不用花括号包起来也是可以的。上面那种只是看起来会统一一点。看你个人喜好
v2 := router.Group("/v2")
v2.POST("/login", loginEndpoint)
v2.POST("/submit", submitEndpoint)
v2.POST("/read", readEndpoint)
router.Run(":8080")
}
异步处理
goroutine 机制可以方便地实现异步处理
func main() {
r := gin.Default()
//1. 异步
r.GET("/long_async", func(c *gin.Context) {
// goroutine 中只能使用只读的上下文 c.Copy()
cCp := c.Copy()
go func() {
time.Sleep(5 * time.Second)
// 注意使用只读上下文
log.Println("Done! in path " + cCp.Request.URL.Path)
}()
})
//2. 同步
r.GET("/long_sync", func(c *gin.Context) {
time.Sleep(5 * time.Second)
// 注意可以使用原始上下文
log.Println("Done! in path " + c.Request.URL.Path)
})
// Listen and serve on 0.0.0.0:8080
r.Run(":8080")
}
接收参数
接收GET参数
路由
router.GET("/user", hello)
控制器 (这里用的接收方法是Query)
func hello(c *gin.Context) {
firstname := c.DefaultQuery("firstname", "Guest") //设置默认参数值
lastname := c.Query("lastname") //获取参数值,c.Request.URL.Query().Get("lastname")的缩写
c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
}
或者
路由 (参数名用:号标记)
router.GET("/user/:name/:action", user)
或者
router.GET("/user/:name/*action", user)
上面这个写法将会匹配/user/:name/开头的所有路由
控制器 (这里的接收方法是Param)
func user(c *gin.Context) {
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, message)
}
接收POST参数
路由
router.POST("/post", post)
控制器
func post(c *gin.Context) {
name := c.PostForm("name")
age := c.PostForm("age")
fmt.Printf("name: %s, age: %s;", name, age)
}
文件上传
单文件上传
路由
router.POST("/upload", upload)
控制器
func upload(c *gin.Context) {
file, _ := c.FormFile("file") //表单的文件name="file"
//文件上传路径和文件名
c.SaveUploadedFile(fil