Gin框架使用(2)|青训营笔记

95 阅读1分钟

分组路由

func main() {
    router := gin.Default()

    // Simple group: v1
    v1 := router.Group("/v1")
    {
            v1.POST("/login", loginEndpoint)
            v1.POST("/submit", submitEndpoint)
            v1.POST("/read", readEndpoint)
    }

    // Simple group: v2
    v2 := router.Group("/v2")
    {
            v2.POST("/login", loginEndpoint)
            v2.POST("/submit", submitEndpoint)
            v2.POST("/read", readEndpoint)
    }

    router.Run(":8080")
}

使用中间件

r := gin.New()

// Global middleware
// Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
// By default gin.DefaultWriter = os.Stdout
r.Use(gin.Logger())

// Recovery middleware recovers from any panics and writes a 500 if there was one.
r.Use(gin.Recovery())

// Per route middleware, you can add as many as you desire.
r.GET("/benchmark", MyBenchLogger(), benchEndpoint)

// Authorization group
// authorized := r.Group("/", AuthRequired())
// exactly the same as:
authorized := r.Group("/")
// per group middleware! in this case we use the custom created
// AuthRequired() middleware just in the "authorized" group.
authorized.Use(AuthRequired())
{
        authorized.POST("/login", loginEndpoint)
        authorized.POST("/submit", submitEndpoint)
        authorized.POST("/read", readEndpoint)

        // nested group
        testing := authorized.Group("testing")
        // visit 0.0.0.0:8080/testing/analytics
        testing.GET("/analytics", analyticsEndpoint)
}

日志记录

// Logging to a file.
f, _ := os.Create("gin.log")
gin.DefaultWriter = io.MultiWriter(f)

自定义日志格式

// LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
// By default gin.DefaultWriter = os.Stdout
router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {

    // your custom format
    return fmt.Sprintf("%s - [%s] "%s %s %s %d %s "%s" %s"\n",
                    param.ClientIP,
                    param.TimeStamp.Format(time.RFC1123),
                    param.Method,
                    param.Path,
                    param.Request.Proto,
                    param.StatusCode,
                    param.Latency,
                    param.Request.UserAgent(),
                    param.ErrorMessage,
    )
}))
router.Use(gin.Recovery())

绑定数据

  • Binding Json
// Binding from JSON
type Login struct {
	User     string `form:"user" json:"user" xml:"user"  binding:"required"`
	Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
// Example for binding JSON ({"user": "manu", "password": "123"})
router.POST("/loginJSON", func(c *gin.Context) {
        var json Login
        if err := c.ShouldBindJSON(&json); err != nil {
                c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
                return
        }

        if json.User != "manu" || json.Password != "123" {
                c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
                return
        }

        c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
})
  • Binding Uri
type Person struct {
    ID string `uri:"id" binding:"required,uuid"`
    Name string `uri:"name" binding:"required"`
}

func main() {
    route := gin.Default()
    route.GET("/:name/:id", func(c *gin.Context) {
            var person Person
            if err := c.ShouldBindUri(&person); err != nil {
                    c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
                    return
            }
            c.JSON(http.StatusOK, gin.H{"name": person.Name, "uuid": person.ID})
    })
    route.Run(":8088")
}
  • Binding Multipart/Urlencoded
type ProfileForm struct {
	Name   string                `form:"name" binding:"required"`
	Avatar *multipart.FileHeader `form:"avatar" binding:"required"`

	// or for multiple files
	// Avatars []*multipart.FileHeader `form:"avatar" binding:"required"`
}

func main() {
	router := gin.Default()
	router.POST("/profile", func(c *gin.Context) {
		// you can bind multipart form with explicit binding declaration:
		// c.ShouldBindWith(&form, binding.Form)
		// or you can simply use autobinding with ShouldBind method:
		var form ProfileForm
		// in this case proper binding will be automatically selected
		if err := c.ShouldBind(&form); err != nil {
			c.String(http.StatusBadRequest, "bad request")
			return
		}

		err := c.SaveUploadedFile(form.Avatar, form.Avatar.Filename)
		if err != nil {
			c.String(http.StatusInternalServerError, "unknown error")
			return
		}

		// db.Save(&form)

		c.String(http.StatusOK, "ok")
	})
	router.Run(":8080")
}