GO_Gin
前言
Gin是一个用Go(Golang)编写的轻量级HTTP web框架,以其运行速度快、API友好和封装优雅著称。Gin框架支持RESTful风格的API设计,允许开发者使用URL定位资源,并通过HTTP请求类型(如GET、POST、PUT、DELETE等)描述操作。
框架介绍
-
安装引入
-
安装 go get -u github.com/gin-gonic/gin 引入 import "github.com/gin-gonic/gin" 示例: package main import "github.com/gin-gonic/gin" func main() { router := gin.Default() router.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) router.Run() // 监听并在 0.0.0.0:8080 上启动服务 }
-
-
路由
-
普通路由
-
router.GET("/", func) router.POST("/login", func) router.Any("/login", func)
-
-
路由分组
-
v1 := router.Group("/v1") { group1.GET("/user", func(c *gin.Context) { c.String(200, "v1 hello world") }) } group2 := router.Group("/v2") { group2.GET("/user", func(c *gin.Context) { c.String(200, "v2 hello world") }) }
-
-
restful
-
router.GET("/user", QueryFunc) //查询 router.Post("/user", AddFunc) // 新增 router.Delete("/user", DeleteFunc) // 删除 router.PUT("/user", UpdateFunc) // 更新(客户端提供完整数据) router.PATCH("/user", PatchUpdateFunc) // 更新(客户端提供需要修改的数据) }
-
-
重定向
-
router.GET("/test", func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, "http://www.google.com/") })
-
-
静态文件
-
//静态文件 router.Static("/static", "./static") //router.StaticFS("/static", http.Dir("static")) router.StaticFile("/f1", "./static/1.txt") // 单独的文件
-
-
-
输出
-
JSON
-
func outputfunc(r *gin.Engine) { r.GET("/user", func(c *gin.Context) { //JSON user := &User{ Name: "111", Password: "123456", } c.JSON(200, user) //c.JSON(200, gin.H{ // "message": "success", // "code": 200, //}) }) }
结果{"Name":"111","Password":"123456"}
-
-
XML
-
func outputfunc(r *gin.Engine) { r.GET("/user", func(c *gin.Context) { //JSON user := &User{ Name: "111", Password: "123456", } c.XML(200, user) }) } 结果 <User> <Name>111</Name> <Password>123456</Password> </User>
-
-
-
-
HTML
-
c.HTML(200, "user.impl", gin.H{ "title": "HTML 测试", }) 结果: HTML 测试
注意:有子目录时, 注意.impl文件的定义templates/posts/index.tmpl {{ define "posts/index.tmpl" }} <html><h1> {{ .title }} </h1> </html> {{ end }}
-
-
-
参数
-
非绑定获取
- URL:127.0.0.1:8080/user/111/222
-
router.GET("/user/:n/:p", func(c *gin.Context) { name := c.Param("n") passwd := c.Param("p") c.JSON(200, gin.H{ "name": name, "password": passwd, }) })
-
URL:127.0.0.1:8080/user?n=1&p=2
-
router.GET("/user", func(c *gin.Context) { name := c.Query("n") passwd := c.Query("p") c.JSON(200, gin.H{ "name": name, "password": passwd, }) })
URL:127.0.0.1:8080/userForm
-
router.POST("/userForm", func(c *gin.Context) { name := c.PostForm("n") passwd := c.PostForm("p") c.JSON(200, gin.H{ "name": name, "password": passwd, }) })
-
参数绑定
-
ShouldBind: 自动识别参数,并绑定对应字段到结构体中 ShouldBindJSON tag:json ShouldBindXML tag:xml ShouldBindQuery tag:form ShouldBindYAML tag:yaml ShouldBindTOML tag:toml ShouldBindHeader tag:header 无法自动识别 ShouldBindUri tag:uri 无法自动识别 type formA struct { Foo string `json:"foo" xml:"foo" binding:"required" form:"foo"` }
-
-
-
模型验证
-
Gin使用 go-playground/validator/v10 进行验证
-
type LoginInfo struct { Username string `json:"username" form:"username" binding:"required"` Password string `json:"password" form:"password" binding:"number"` Email string `json:"email" form:"email" binding:"email"` } func Validator() { r := gin.Default() r.GET("/", func(c *gin.Context) { login := LoginInfo{} err := c.ShouldBind(&login) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, login) }) err := r.Run(":8080") if err != nil { panic(err) } }
-
-
自定义验证器
-
import ( "net/http" "reflect" "time" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" ) // Booking 包含绑定和验证的数据。 type Booking struct { CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"` CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"` } var bookableDate validator.Func = func(fl validator.FieldLevel) bool { date, ok := fl.Field().Interface().(time.Time) if ok { today := time.Now() if today.After(date) { return false } } return true } func main() { route := gin.Default() if v, ok := binding.Validator.Engine().(*validator.Validate); ok { v.RegisterValidation("bookabledate", bookableDate) } route.GET("/bookable", getBookable) route.Run(":8085") } func getBookable(c *gin.Context) { var b Booking if err := c.ShouldBindWith(&b, binding.Query); err == nil { c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"}) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } }
-
-
-
中间件
-
调用栈
-
func mw1() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("mw1 before") c.Next() fmt.Println("mw1 after") } } func mw2() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("mw2 before") c.Next() fmt.Println("mw2 after") } } func Middleware() { r := gin.Default() r.GET("/", mw1(), mw2(), func(c *gin.Context) { fmt.Println("self") c.String(http.StatusOK, "self") }) err := r.Run(":8080") if err != nil { panic(err) } } 输出: mw1 before mw2 before self mw2 after mw1 after
-
-
使用中间件
-
func middleFunc(router *gin.Engine) { user := router.Group("/user", gin.BasicAuth(gin.Accounts{ "user": "123456", })) user.GET("/name", func(c *gin.Context) { user := c.MustGet(gin.AuthUserKey).(string) c.String(http.StatusOK, user) }) }
-
-
-
HTTPS
-
自有证书
Openssl 生成证书,如果只是提供API服务,可以用没有经过认证的证书,如果是网站,则需要认证证书
-
router.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-
-
开源免费认证证书(Let's Encrypt)
-
package main import ( "log" "github.com/gin-gonic/autotls" "github.com/gin-gonic/gin" "golang.org/x/crypto/acme/autocert" ) func main() { router := gin.Default() // Ping handler router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) m := autocert.Manager{ Prompt: autocert.AcceptTOS, HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"), Cache: autocert.DirCache("/var/www/.cache"), } log.Fatal(autotls.RunWithManager(r, &m)) }
-
-

浙公网安备 33010602011771号