Gin 是一个高性能 Go Web 框架。GitHub
安装 go get -u github.com/gin-gonic/gin import "github.com/gin-gonic/gin" Hello World package main import ( "net/http" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "pong"}) }) r.Run() // 0.0.0.0:8080 } go run main.go 路由 HTTP 方法 router.GET("/someGet", getting) router.POST("/somePost", posting) router.PUT("/somePut", putting) router.DELETE("/someDelete", deleting) router.PATCH("/somePatch", patching) 路径参数 // 匹配 /user/john,不匹配 /user/ router.GET("/user/:name", func(c *gin.Context) { name := c.Param("name") c.String(http.StatusOK, "Hello %s", name) }) // 匹配 /user/john/send 等 router.GET("/user/:name/*action", func(c *gin.Context) { name := c.Param("name") action := c.Param("action") c.String(http.StatusOK, name+" is "+action) }) Query 参数 // /welcome?firstname=Jane&lastname=Doe router.GET("/welcome", func(c *gin.Context) { firstname := c.DefaultQuery("firstname", "Guest") lastname := c.Query("lastname") c.String(http.StatusOK, "Hello %s %s", firstname, lastname) }) Post 参数 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}) }) 路由分组 v1 := router.Group("/v1") { v1.POST("/login", loginEndpoint) v1.POST("/submit", submitEndpoint) } 中间件 r := gin.New() r.Use(gin.Logger()) r.Use(gin.Recovery()) authorized := r.Group("/") authorized.Use(AuthRequired()) { authorized.POST("/login", loginEndpoint) } 文件上传 // 单文件 router.POST("/upload", func(c *gin.Context) { file, _ := c.FormFile("file") c.SaveUploadedFile(file, "./"+file.Filename) c.String(http.StatusOK, "'%s' uploaded!", file.Filename) }) // 多文件 router.POST("/upload", func(c *gin.Context) { form, _ := c.MultipartForm() files := form.File["upload[]"] for _, file := range files { c.SaveUploadedFile(file, "./"+file.Filename) } c.String(http.StatusOK, "%d files uploaded!", len(files)) }) 模型绑定 type Login struct { User string `form:"user" json:"user" binding:"required"` Password string `form:"password" json:"password" binding:"required"` } router.POST("/login", func(c *gin.Context) { var json Login if err := c.ShouldBindJSON(&json); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"status": "logged in"}) }) Cookie router.GET("/cookie", func(c *gin.Context) { cookie, err := c.Cookie("gin_cookie") if err != nil { c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true) } _ = cookie }) 优雅重启 srv := &http.Server{Addr: ":8080", Handler: router} go srv.ListenAndServe() quit := make(chan os.Signal, 1) signal.Notify(quit, os.Interrupt) <-quit ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() srv.Shutdown(ctx) 测试 func TestPingRoute(t *testing.T) { router := setupRouter() w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/ping", nil) router.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) assert.Equal(t, "pong", w.Body.String()) } 参考 gin 中文文档