Web开发学习手记(二):gin框架

Web开发学习手记(二):gin框架

前言

冰岩作坊的各种产品都与互联网相关,不可避免地会用到Go语言的网络框架,其中,gin就是一个使用广泛的框架。

新人任务中,我用gin完成了若干实例的开发,学习了gin的一些使用方法。这篇文章整理了我接触过的部分功能。由于使用的场景有限,这里只列举了有限的几个内容。

Router

Router,即路由器(不是一个小盒子那个),功能是监听某个端口的HTTP请求,并根据请求的URL用不同的Handler处理。

在gin中,可以通过gin.Default()获得一个Router,它的类型是gin.Engine。你可以将Handler和Middleware添加到这个Router上,使它按照规则处理请求。

对于Handler,你可以通过Router的GET、POST等方法绑定对于某一类型请求的Handler函数,并指定绑定的URL。

对于Middleware,你可以通过Router的Use方法绑定一个Middleware函数。一般在使用Middleware的时候,常常使用Group对某一URL的请求分类,在绑定Middleware的同时绑定Handler。

Handler

Handler,即处理函数,功能是处理指定的请求,并根据请求给出相应的响应。

在gin中,Handler应当是一个接受一个*gin.Context类型参数的函数。使用JSON进行C/S通信是一种很常用的方法,你可以通过gin.ContextBindJSON方法将请求体中的JSON内容解析进指定结构体中。结构体内的变量需要设置json反射标签。以下给出一个使用例。

type ReqType struct {
    var Data int `json:"data"`
}

func main() {
    router := gin.Default()
    router.POST("/", func(context *gin.Context) {
        var req ReqType
        err := context.BindJSON(&req)
        if err != nil {
            fmt.Println(err.Error())
            return
        }
        fmt.Println(req.Data)
    })
    _ = router.Run()
}

gin也可以很方便地使用JSON作出响应。gin.H是一个对map的简写,你可以用它简单地创建一个map,并用context.JSON方法作出响应。以下给出一个使用例。

type ReqType struct {
    var Data int `json:"data"`
}

func main() {
    router := gin.Default()
    router.POST("/", func(context *gin.Context) {
        var req ReqType
        err := context.BindJSON(&req)
        if err != nil {
            fmt.Println(err.Error())
            return
        }
        context.JSON(http.StatusOK, gin.H{
            "message": req.Data,
        })
    })
    _ = router.Run()
}

Handler还可以处理其他类型的请求,如GET、OPTIONS等,由于我没有接触过这些请求的用法,这里便留空了。

Middlerware

Middleware,即中间件,功能是在请求发给Handler之前对请求进行一些处理,比如验证权限。在我的实践中,我实现了一个验证JWT的Middleware,用于API的认证。

gin中提供了router.Group这一方法,可以对Router的某一URL进行多个操作,例如绑定Middleware和绑定Handler。可以先用router.Group获取到一个RouterGroup,然后用group.Use绑定一个Middleware。

Middleware的实现是一个接受一个*gin.Context类型的参数的函数。在这个函数中,你可以分析请求,如果需要拒绝请求,使用context.Abort方法,如果请求可以继续处理,使用context.Next方法。以下是一个使用Middleware对API做简单验证的例子。

type ReqType struct {
    var Pass int `json:"pass"`
}

func main() {
    router := gin.Default()
    
    api := router.Group("/api")
    api.Use(func(context *gin.Context) {
        var req ReqType
        err := context.BindJSON(&req)
        if err != nil || req.Pass != "password" {
            context.JSON(http.StatusUnauthorized, gin.H{
                "error": "error!",
            })
            context.Abort()
            return
        }
        context.Next()
    })
    api.POST("/", func(context *gin.Context) {
        context.JSON(http.StatusOK, gin.H{
            "message": "welcome",
        })
    })

    _ = router.Run()
}


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据