# gin
## gin限流
https://www.liwenzhou.com/posts/Go/ratelimit/
## gin原始碼結構
https://github.com/jincheng9/go-tutorial/tree/main/workspace/gin/02
### 學習點

下面var是確保上面struct實現對應的interface

這個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

use 往group裡面的childHandler slince塞
然後當你get ...等方法去啟動 會去註冊route 並把你的hand也塞在childHanler
最後在run那邊的處理request

會將對應的路由放在context
然後跑next
這邊會跑每一個hand 所以middware跟原本的hanler都會跑

## gin-cors
https://pjchender.dev/golang/gin-cors/

## sessions
## router tree
https://www.liwenzhou.com/posts/Go/gin-sourcecode/#autoid-0-1-0
## tree
為什麼http方法用tree不用map

因為hash沒這麼快加上method也就那幾個 所以跑loop比較快
## node
https://www.liwenzhou.com/posts/Go/gin-sourcecode/#autoid-0-1-1
### :id 可變參數

bind url自訂去做驗證
簡單版本用context去抓就好

### ShouldBindJson
去看struct的tag
會做驗證

### validated
去看go-playgroud套件
他也是依賴別第三方套件
## middware
## 預設提供
auth

log

formaterr function 可以輸出log
recover 防止崩潰 接觸錯誤

### about and next
https://blog.csdn.net/cyberspecter/article/details/100602552
### c.Copy()
在中间件或处理程序中启动新的Goroutines时,你不应该使用其中的原始上下文,你必须使用只读副本(c.Copy())

## 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")
}
```
### 映射查询字符串或表单参数

## 自定义 HTTP 配置


## 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://www.51cto.com/article/720688.html
### tag
time_format tag is only used in form binding, not json
## time_format

只能在bind
Json不能用
## 文件
### 單
formFile

### 多

多

## request body 绑定到不同的结构体中
https://learnku.com/docs/gin-gonic/1.7/examples-bind-body-into-dirrerent-structs/11385
c.ShouldBindBodyWith 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法
###### tags: `Go`