Gin
// 初識 Gin框架
//下載(可能會下載不全。缺什么get什么即可)
//go get -u -v github.com/gin-gonic/gin
package main
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, map[string]string{"name": "zjhah"})
})
err := r.Run()
log.Fatalln(err)
//
}
Gin框架的熱加載 realize
// 下載
go get github.com/oxequa/realize
// 下載之后
realize init 初始化 直接下步一步退出即可
realize start 就是直接將gin運行起來 進行熱加載
- Gin框架—log (Gin 框架 - 使用 logrus 進行日志記錄)
約定日志格式字段:
請求時間
, 日志級別
, 狀態碼
, 執行時間
, 請求IP
, 請求方式
,請求路由
Logrus
API的URL設計規則restful api
1. api有版本信息
/v1/xxxx
/v2/xxx
2.盡可能的使用復數, 含義明確 名詞最好
/v1/users
/v1/topics
3.使用GET參數規划數據展現規則
/v1/users
/v1/users?limit=10 //只顯示10條
- 路由組
router := gin.Default()
r := router.Group("/v1/") // group組
r.GET("/", FirstJson)
r.POST("/", PostTest)
_ = router.Run(":9000")
- api參數
// 這是api參數
r.GET("/:name", FirstJson)
c.param("name")
- URL參數
?key=xxx & name=xxx
- 表單取文件
r.Post("/v1/:file")
file := c.Formfile("file")
_ := c.saveUploadFile(file, file.FileName)
- 表單上傳多個文件
// 設置上傳的文件的最大容量
r.MaxMultipartMemory = 8*1024
// 獲取多個文件
form, _ := c.MultipartForm()
files := form.File["file"]
然后循環像上邊單個存一樣
- 接收數據的結構體
package main
import (
"fmt"
"github.com/gin-gonic/gin"
_ "github.com/sirupsen/logrus"
_ "log"
"net/http"
)
// 接收數據的結構體
type Option struct {
User string `form:"username" json:"username" uri:"user" xml:"user" binding:"required"` // binding必須不能為空
Password string `form:"password" json:"password" xml:"password" uri:"password"`
}
func main() {
// 創建路由
// default 創建的路由默認使用了兩個中間件 logger()日志 recovery() 自動恢復
router := gin.Default()
// 原生的是這個 是不會使用這兩個中間件的
// router := gin.New()
router.Use(gin.Logger())
r := router.Group("/v1")
{
r.POST("/JsonTest", JsonTest)
}
_ = router.Run(":9000")
//
}
func JsonTest(c *gin.Context) {
// Bind() 默認解析並綁定form格式
// 根據請求頭中的 content-type 判斷數據類型
var Form Option
errs := c.Bind(&Form)
if errs != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": errs.Error()})
}
fmt.Println(Form)
// 聲明接收的變量 json綁定
var jsonData Option
// 接收到的數據 綁定到jsonData結構體 ShouldBindJSON
err := c.ShouldBindJSON(&jsonData)
fmt.Println(jsonData)
if err != nil {
// gin.H 封裝了生成json數據的工具
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if jsonData.User != "root" || jsonData.Password != "123" {
c.JSON(http.StatusBadRequest, gin.H{"status_code": "302"})
return
}
c.JSON(http.StatusOK, gin.H{"status": 200})
}
- HTML模版渲染 類似於python render
// 加載模版文件
// router.LoadHTMLFiles("templates/index.html")
router.LoadHTMLGlob("templates/*")
// 返回狀態碼。返回html渲染文件。返回想要在html文件中所需要的數據
c.HTML("200", "index.html", gin.H{"title": "ccn"})
- 重定向
r.GET("/redirect", Redirects)
func Redirects(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.taobao.com/")
}
- 同步異步
// 異步
func Async(c *gin.Context) {
// go routine 機制可以方便的實現異步處理
// 注意: 在啟動新的goroutine時, 不應該使用原始上下文, 必須使用他的只讀副本
copyContent := c.Copy()
// go func 處理的就是要處理的數據之類的 例如上傳文件, 修改數據, 添加數據
go func() {
time.Sleep(5 * time.Second)
fmt.Println(copyContent.Request.Method, copyContent.Request.Header, copyContent.Request.RemoteAddr, copyContent.Request.RequestURI)
}()
c.JSON(http.StatusOK, gin.H{"name": 123})
}
// 正常的都是同步
- gin中間件
//gin可以構建中間件, 但它只對注冊過的路由函數起作用
//對於分組路由, 嵌套使用中間件, 可以限定中間件的作用范圍
//中間件分為全局中間件, 單個路由中間件和群組中間件
//gin中間件必須是一個gin.HandlerFun類型
// 全局中間件所有的中間件都會經過
func GinMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("中間件開始執行")
// 設置變量到context的key中, 后邊可以通過Get()獲取
c.Set("request", "中間件")
// 執行router綁定的函數
c.Next()
// 執行完中間件后執行的代碼
status := c.Writer.Status()
fmt.Println(status)
}
}
c.GET("request")
- gin生成接口文檔 swagger
- JSON web token JWT
- 令牌桶 漏桶