复盘web库gin框架

安装

go get -u github.com/gin-gonic/gin

基础使用

package main

import (
  "net/http"

  "github.com/gin-gonic/gin"
)

func main() {
  r := gin.Default()
  r.GET("/ping", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{
      "message": "pong",
    })
  })
  r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

复杂使用

gin.SetMode(gin.ReleaseMode)
router := gin.Default()

// 不存在的路由
router.NoRoute(controller.NotFound)
// 不存在的方法
router.NoMethod(controller.NotFound)
// 静态文件目录
//router.Static("/files", "./files")
// 静态文件
router.StaticFile("/favicon.ico", "./static/favicon.ico")
// 静态文件目录
router.Static("/static", "./static")
// 模板标签
router.Delims("{{{", "}}}")
// 模板加载路径
router.LoadHTMLGlob("views/**/**/*")
// 模板调用函数
router.SetFuncMap(template.FuncMap{
    "SafeJs":              view.SafeJS,
})

// 使用中间件
router.Use(middleware.Cors())
// 实例化控制器
controllersV1 := new(v1.Controller)

// 路由分组
api := router.Group("api")
{
    // 无需权限校验的分组
    apiV1 := api.Group("v1")
    {
        // 设置路由 POST、GET等
        apiV1.GET("user/test_a", controllersV1.TestA)
        apiV1.GET("user/test_b", controllersV1.TestB)
        apiV1.POST("user/test_c", controllersV1.TestC)
    }
    // 需要权限校验的分组
    apiV1.Use(middleware.JWTAuth())
    {
        apiV1.GET("user/test_d", controllersV1.TestD)
    }

    // 需要权限校验
    //apiV1.Use(middleware.CasbinRBAC())

}
router.Run()

中间件的编写

// 跨域中间件
// Cors 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
    return func(c *gin.Context) {
        method := c.Request.Method
        origin := c.Request.Header.Get("Origin")
        c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
        c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
        c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
        // 放行所有OPTIONS方法
        if method == "OPTIONS" {
            c.AbortWithStatus(http.StatusNoContent)
        }
        // 处理请求
        c.Next()
    }
}
// JWT 处理中间件
func JWTAuth() gin.HandlerFunc {
    return func(c *gin.Context) {
        // jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
        token := c.Request.Header.Get("x-token")
        if token == "" {
            c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录或非法访问"})
            c.Abort()
            return
        }
        fmt.Println("JWTAuth")
        c.Set("claims", 11)
        c.Next()
    }
}

控制器

# 结构体形式的控制器
type IndexApi struct {
}

// Index
func (a IndexApi) Index(c *gin.Context) {
    c.JSON(200, gin.H{"message": "hello world"})
}
# 单个函数控制器方法
func Index(c *gin.Context) {
    c.JSON(200, gin.H{"message": "hello world"})
}

数据输出

c.JSON(200, gin.H{"message": "hello world"})
其他的善用搜索与文档