# gin ## gin限流 https://www.liwenzhou.com/posts/Go/ratelimit/ ## gin原始碼結構 https://github.com/jincheng9/go-tutorial/tree/main/workspace/gin/02 ### 學習點 ![](https://i.imgur.com/J7jiR3R.png) 下面var是確保上面struct實現對應的interface ![](https://i.imgur.com/AJKJp6F.png) 這個for等於 for i:=0 ;i<len(t); i++ 但圖片裡面的寫的比較好 可以不用每次都計算len route註冊 default去創建group group有use或其他就放在group裡面的handler 然後get post之類的註冊 會將group handlerChild放入engin裡面的method tree裡面對應的node 加上自己handler一起放入 engin去啟動server 這邊會抓對應的method tree的node去處理hanler 都放入context 然後跑next一個一個跑 所以當你middware再跑c.next就會去抓一個handler 所以自己的handler才最後註冊 ### http https://blog.csdn.net/kevin_tech/article/details/121173547 ### route https://segmentfault.com/a/1190000019101583 ### 参数 https://segmentfault.com/a/1190000019130634 ### route and middware ![](https://i.imgur.com/fU7uduz.png) use 往group裡面的childHandler slince塞 然後當你get ...等方法去啟動 會去註冊route 並把你的hand也塞在childHanler 最後在run那邊的處理request ![](https://i.imgur.com/vwjX0K7.png) 會將對應的路由放在context 然後跑next 這邊會跑每一個hand 所以middware跟原本的hanler都會跑 ![](https://i.imgur.com/Tx4zqC1.png) ## gin-cors https://pjchender.dev/golang/gin-cors/ ![](https://i.imgur.com/ttIZPLY.png) ## sessions ## router tree https://www.liwenzhou.com/posts/Go/gin-sourcecode/#autoid-0-1-0 ## tree 為什麼http方法用tree不用map ![](https://i.imgur.com/obFg29R.png) 因為hash沒這麼快加上method也就那幾個 所以跑loop比較快 ## node https://www.liwenzhou.com/posts/Go/gin-sourcecode/#autoid-0-1-1 ### :id 可變參數 ![](https://i.imgur.com/xBcH1L4.png) bind url自訂去做驗證 簡單版本用context去抓就好 ![](https://i.imgur.com/PYhFAf2.png) ### ShouldBindJson 去看struct的tag 會做驗證 ![](https://i.imgur.com/s2GOtBt.png) ### validated 去看go-playgroud套件 他也是依賴別第三方套件 ## middware ## 預設提供 auth ![](https://i.imgur.com/Kvy4bmx.png) log ![](https://i.imgur.com/8wT3qMz.png) formaterr function 可以輸出log recover 防止崩潰 接觸錯誤 ![](https://i.imgur.com/iioGqSx.png) ### about and next https://blog.csdn.net/cyberspecter/article/details/100602552 ### c.Copy() 在中间件或处理程序中启动新的Goroutines时,你不应该使用其中的原始上下文,你必须使用只读副本(c.Copy()) ![](https://i.imgur.com/7jpam8s.png) ## HTML 渲染 https://learnku.com/docs/gin-gonic/1.5/examples-html-rendering/6160 ## HTTP2 server 推送 http.Pusher 仅支持 go1.8+。 https://learnku.com/docs/gin-gonic/1.5/examples-http2-server-push/6161 ## query ### PostForm ``` 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") } ``` ### 绑定 HTML 复选框 ``` ... type myForm struct { Colors []string `form:"colors[]"` } ... func formHandler(c *gin.Context) { var fakeForm myForm c.ShouldBind(&fakeForm) c.JSON(200, gin.H{"color": fakeForm.Colors}) } ... ``` ### 绑定 Uri ``` package main import "github.com/gin-gonic/gin" 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(400, gin.H{"msg": err}) return } c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID}) }) route.Run(":8088") } ``` ### 映射查询字符串或表单参数 ![](https://i.imgur.com/OD2Xh9x.png) ## 自定义 HTTP 配置 ![](https://i.imgur.com/fr1dCrD.png) ![](https://i.imgur.com/IYvvNQU.png) ## PureJSON 通常,JSON 使用 unicode 替换特殊 HTML 字符,例如 < 变为 \ u003c。如果要按字面对这些字符进行编码,则可以使用 PureJSON。Go 1.6 及更低版本无法使用此功能。 ``` func main() { r := gin.Default() // 提供 unicode 实体 r.GET("/json", func(c *gin.Context) { c.JSON(200, gin.H{ "html": "<b>Hello, world!</b>", }) }) // 提供字面字符 r.GET("/purejson", func(c *gin.Context) { c.PureJSON(200, gin.H{ "html": "<b>Hello, world!</b>", }) }) // 监听并在 0.0.0.0:8080 上启动服务 r.Run(":8080") } ``` ## 自定义验证器 (Gin Binding) https://learnku.com/docs/gin-gonic/1.7/examples-custom-validators/11396 ![](https://i.imgur.com/EbvTFNP.png) ![](https://i.imgur.com/74gfMdS.png) https://www.51cto.com/article/720688.html ### tag time_format tag is only used in form binding, not json ## time_format ![](https://i.imgur.com/71Tbanf.png) 只能在bind Json不能用 ## 文件 ### 單 formFile ![](https://i.imgur.com/jXJD9Th.png) ### 多 ![](https://i.imgur.com/WMuoZDI.png) 多 ![](https://i.imgur.com/WMuoZDI.png) ## request body 绑定到不同的结构体中 https://learnku.com/docs/gin-gonic/1.7/examples-bind-body-into-dirrerent-structs/11385 c.ShouldBindBodyWith 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法 ###### tags: `Go`