整体架构
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Content) {
c.JSON(http.StatusOK, gin.H{
"code": "P10001"
})
})
r.Run()
}
详解
直接获取请求参数
// parameters in path
c.Param("name")
// querystring param
c.DefaultQuery("name", "Guest")
c.Query("name")
//form
c.PostForm("name")
c.DefaultPostForm("name", "Guest")
// map as querystring or postform parameters
ids := c.QueryMap("ids")
names := c.PostFormMap("names")
c.JSON(http.StatusOK, gin.H{
"ids": ids,
"names": names,
})
文件上传
// upload file
file, _ := c.FormFile("file")
// Upload the file to specific dst.
// c.SaveUploadedFile(file, dst)
// multiple files
form, _ := c.MultipartForm()
files := form.File["upload[]"]
路由
//grouping routes
v1 := router.Group("/v1")
{
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}
中间件middleware
//use r := gin.New() instead of r := gin.Default()
r := gin.New()
r.Use(gin.Logger())
authorized := r.Group("/")
authorized.Use(AuthRequired())
{
authorized.POST("/login", loginEndpoint)
authorized.POST("/submit", submitEndpoint)
authorized.POST("/read", readEndpoint)
}
日志
// write log file
// 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)
Model binding and validation
Must bind
- Bind, BindJSON, BindXML, BindQuery, BindYAML, BindHeader
Should bind
- ShouldBind, ShouldBindJSON, ShouldBindXML, ShouldBindQuery, ShouldBindYAML, ShouldBindHeader
type Login struct {
User string form:"user" json:"user" xml:"user" binding:"required"
Password string form:"password" json:"password" xml:"password" binding:"required"
}
func main() {
r := gin.Default()
// Example for binding JSON ({"user": "manu", "password": "123"})
r.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"})
})
Validators
//todo
静态文件服务
r.Static("/assets", "./assets")
HTML渲染
r := gin.Default()
r.LoadHTMLGlob("templates/*")
//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
r.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "Main website",
})
})
//templates/index.tmpl
{{ .title }}
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/**/*")
router.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"title": "Posts",
})
})
router.GET("/users/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
"title": "Users",
})
})
router.Run(":8080")
}
{{ define "posts/index.tmpl" }}
{{ .title }}
Using posts/index.tmpl
{{ end }}
{{ define "users/index.tmpl" }}
{{ .title }}
Using users/index.tmpl
{{ end }}