zoukankan      html  css  js  c++  java
  • Golang Gin(中)

    快速入门

    Using GET, POST, PUT, PATCH, DELETE and OPTIONS

    func main() {
        // Creates a gin router with default middleware:
        // logger and recovery (crash-free) middleware
        router := gin.Default()
    
        router.GET("/someGet", getting)
        router.POST("/somePost", posting)
        router.PUT("/somePut", putting)
        router.DELETE("/someDelete", deleting)
        router.PATCH("/somePatch", patching)
        router.HEAD("/someHead", head)
        router.OPTIONS("/someOptions", options)
    
        // By default it serves on :8080 unless a
        // PORT environment variable was defined.
        router.Run()
        // router.Run(":3000") for a hard coded port
    }

    Parameters in path

    func main() {
        router := gin.Default()
    
        // This handler will match /user/john but will not match /user/ or /user
        router.GET("/user/:name", func(c *gin.Context) {
            name := c.Param("name")
            c.String(http.StatusOK, "Hello %s", name)
        })
    
        // However, this one will match /user/john/ and also /user/john/send
        // If no other routers match /user/john, it will redirect to /user/john/
        router.GET("/user/:name/*action", func(c *gin.Context) {
            name := c.Param("name")
            action := c.Param("action")
            message := name + " is " + action
            c.String(http.StatusOK, message)
        })
    
        // For each matched request Context will hold the route definition
        router.POST("/user/:name/*action", func(c *gin.Context) {
            c.FullPath() == "/user/:name/*action" // true
        })
    
        router.Run(":8080")
    }

    Querystring parameters

    func main() {
        router := gin.Default()
    
        // Query string parameters are parsed using the existing underlying request object.
        // The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe
        router.GET("/welcome", func(c *gin.Context) {
            firstname := c.DefaultQuery("firstname", "Guest")
            lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
    
            c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
        })
        router.Run(":8080")
    }

    Multipart/Urlencoded Form

    func main() {
        router := gin.Default()
    
        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,
            })
        })
        router.Run(":8080")
    }

    Another example: query + post form

    POST /post?id=1234&page=1 HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    name=manu&message=this_is_great
    func main() {
        router := gin.Default()
    
        router.POST("/post", func(c *gin.Context) {
    
            id := c.Query("id")
            page := c.DefaultQuery("page", "0")
            name := c.PostForm("name")
            message := c.PostForm("message")
    
            fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
        })
        router.Run(":8080")
    }
    id: 1234; page: 1; name: manu; message: this_is_great

    Map as querystring or postform parameters

    POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    names[first]=thinkerou&names[second]=tianou
    func main() {
        router := gin.Default()
    
        router.POST("/post", func(c *gin.Context) {
    
            ids := c.QueryMap("ids")
            names := c.PostFormMap("names")
    
            fmt.Printf("ids: %v; names: %v", ids, names)
        })
        router.Run(":8080")
    }
    ids: map[b:hello a:1234]; names: map[second:tianou first:thinkerou]

    Upload files

    Single file

    The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.

    func main() {
        router := gin.Default()
        // Set a lower memory limit for multipart forms (default is 32 MiB)
        router.MaxMultipartMemory = 8 << 20  // 8 MiB
        router.POST("/upload", func(c *gin.Context) {
            // single file
            file, _ := c.FormFile("file")
            log.Println(file.Filename)
    
            // Upload the file to specific dst.
            c.SaveUploadedFile(file, dst)
    
            c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
        })
        router.Run(":8080")
    }

    How to curl:

    curl -X POST http://localhost:8080/upload 
      -F "file=@/Users/appleboy/test.zip" 
      -H "Content-Type: multipart/form-data"

    Multiple files

    See the detail example code.

    func main() {
        router := gin.Default()
        // Set a lower memory limit for multipart forms (default is 32 MiB)
        router.MaxMultipartMemory = 8 << 20  // 8 MiB
        router.POST("/upload", func(c *gin.Context) {
            // Multipart form
            form, _ := c.MultipartForm()
            files := form.File["upload[]"]
    
            for _, file := range files {
                log.Println(file.Filename)
    
                // Upload the file to specific dst.
                c.SaveUploadedFile(file, dst)
            }
            c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
        })
        router.Run(":8080")
    }

    How to curl:

    curl -X POST http://localhost:8080/upload 
      -F "upload[]=@/Users/appleboy/test1.zip" 
      -F "upload[]=@/Users/appleboy/test2.zip" 
      -H "Content-Type: multipart/form-data"

    Grouping routes

    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")
    }

    Blank Gin without middleware by default

    Use

    r := gin.New()

    instead of

    // Default With the Logger and Recovery middleware already attached
    r := gin.Default()

    Using middleware

    func main() {
        // Creates a router without any middleware by default
        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")
            testing.GET("/analytics", analyticsEndpoint)
        }
    
        // Listen and serve on 0.0.0.0:8080
        r.Run(":8080")
    }

    Custom Recovery behavior

    func main() {
        // Creates a router without any middleware by default
        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.CustomRecovery(func(c *gin.Context, recovered interface{}) {
            if err, ok := recovered.(string); ok {
                c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
            }
            c.AbortWithStatus(http.StatusInternalServerError)
        }))
    
        r.GET("/panic", func(c *gin.Context) {
            // panic with a string -- the custom middleware could save this to a database or report it to the user
            panic("foo")
        })
    
        r.GET("/", func(c *gin.Context) {
            c.String(http.StatusOK, "ohai")
        })
    
        // Listen and serve on 0.0.0.0:8080
        r.Run(":8080")
    }

    How to write log file

    func main() {
        // Disable Console Color, you don't need console color when writing the logs to file.
        gin.DisableConsoleColor()
    
        // Logging to a file.
        f, _ := os.Create("gin.log")
        gin.DefaultWriter = io.MultiWriter(f)
    
        // Use the following code if you need to write the logs to file and console at the same time.
        // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
    
        router := gin.Default()
        router.GET("/ping", func(c *gin.Context) {
            c.String(200, "pong")
        })
    
        router.Run(":8080")
    }

    Custom Log Format

    func main() {
        router := gin.New()
    
        // 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"
    ",
                    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())
    
        router.GET("/ping", func(c *gin.Context) {
            c.String(200, "pong")
        })
    
        router.Run(":8080")
    }

    Sample Output

    ::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "

    Controlling Log output coloring

    By default, logs output on console should be colorized depending on the detected TTY.

    Never colorize logs:

    func main() {
        // Disable log's color
        gin.DisableConsoleColor()
        
        // Creates a gin router with default middleware:
        // logger and recovery (crash-free) middleware
        router := gin.Default()
        
        router.GET("/ping", func(c *gin.Context) {
            c.String(200, "pong")
        })
        
        router.Run(":8080")
    }

    Always colorize logs:

    func main() {
        // Force log's color
        gin.ForceConsoleColor()
        
        // Creates a gin router with default middleware:
        // logger and recovery (crash-free) middleware
        router := gin.Default()
        
        router.GET("/ping", func(c *gin.Context) {
            c.String(200, "pong")
        })
        
        router.Run(":8080")
    }
  • 相关阅读:
    CSS3 Transitions 你可能不知道的知识点
    css规范
    移动应用表单设计秘籍
    SVN和Git的一些用法总结
    让Terminal显示git分支
    JavaScript正则表达式下——相关方法
    requests模块
    flask模块
    os模块
    简单的socket编程
  • 原文地址:https://www.cnblogs.com/peteremperor/p/13896005.html
Copyright © 2011-2022 走看看