解读Golang的web利器-----Gin

由于工作变动,开始接触golang服务器端的开发,目前的公司的后端用的全部是go,之前c++用得比较多,现在将自己的技术栈全部切换为golang那一套东西。go有一个好爹,生态也逐渐起来了,尤其在国内,社区和开源项目都很活跃,框架一个又一个。相比c++,它的开发效率更高,以及对并发的原生支持,使得go更能胜任后端服务的实现,包括restful的接口、并发模型等等。


之前花了一个礼拜学习了go的语法和特性,看得差不多了,会c++,感觉自己学什么语言都很快,现在开始逐步接手团队的代码。我们的后端由一个个微服务组成,框架选的是比较流行的gin,用来做路由和响应。下面这个是gin的开源地址:https://github.com/gin-gonic/gin


其实官方文档写得已经比较清楚了,基本上看一遍直接可以用了,但毕竟是全英文的,我这里将它大致简单翻译了一下,并加入了一些自己的理解。


Gin


首先,安装很简单,在gogland的terminal里敲go get即可,这些公共的包最好放在一个公共的地方,和工程分离开来,这些都可以在gopath里设置,这里就不细说了。

 func main() {

    router := gin.Default()
    router.GET("/someGet", getting)
    router.POST("/somePost", posting)
    router.PUT("/somePut", putting)
    router.DELETE("/someDelete", deleting)
    router.PATCH("/somePatch", patching)
    router.HEAD("/someHead", head)
    router.OPTIONS("/someOptions", options)
    router.Run()
}



上面这段代码就实现了restful接口的和url之间的路由,第一个参数是url,第二个参数是对应的方法。gin会把request和response都封装到gin.Context的上下文环境。最后启动路由的Run方法监听端口。


Param方法

func main() {
    router := gin.Default()

    // This handler will match /user/john but will not match neither /user/ or /user
    router.GET("/user/:name", func(c *gin.Context) {
        myParam:= c.Param("name")
        c.String(http.StatusOK, "Hello %s", name)
    })
    router.Run(":8080")
}



通过Param方法,可以获取url中的:XXX的参数,比如针对上述,如果我的url为/user/john,我就可以通过myParam:= c.Param("name")来获得john这个参数值。


Query方法

func main() {
    router := gin.Default()

    // Query string parameters are parsed using the existing underlying request object.
    // The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe
    router.GET("/welcome", func(c *gin.Context) {
        myFirstname := c.DefaultQuery("firstname", "Guest")
        myLastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")

        c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
    })
    router.Run(":8080")
}



通过Query方法,可以针对Get请求的显式参数进行获取。比如针对上述,如果我的url为/welcome?firstname=Jane&lastname=Doe,我就可以通过myLastname := c.Query("lastname")来获得Jane和Doe这些参数值。


PostForm方法

/* 这是一个post请求

POST /post?id=1234&page=1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

name=manu&message=this_is_great
*/

func main() {
    router := gin.Default()

    router.POST("/post", func(c *gin.Context) {

        id := c.Query("id")
        page := c.DefaultQuery("page", "0")
        name := c.PostForm("name")
        message := c.PostForm("message")

        fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
    })
    router.Run(":8080")
}



上面是个post请求,DefaultQuery方法(相比于Query方法,可提供默认值)用于获取url中的参数,而PostForm方法解析的是body体中x-www-form-urlencodedfrom-data的格式的参数(application/json格式的我下面会讲)


Bind方法

// Binding from JSON
type Login struct {
    User     string `form:"user" json:"user" binding:"required"`
    Password string `form:"password" json:"password" binding:"required"`
}

func main() {
    router := gin.Default()

    // Example for binding JSON ({"user": "manu", "password": "123"})
    router.POST("/loginJSON", func(c *gin.Context) {
        var myLogIn Login
        if c.BindJSON(&myLogIn) == nil {
            if json.User == "manu" && json.Password == "123" {
                c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
            } else {
                c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
            }
        }
    })

    // Example for binding a HTML form (user=manu&password=123)
    router.POST("/loginForm", func(c *gin.Context) {
        var form Login
        // This will infer what binder to use depending on the content-type header.
        if c.Bind(&form) == nil {
            if form.User == "manu" && form.Password == "123" {
                c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
            } else {
                c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
            }
        }
    })

    // Listen and serve on 0.0.0.0:8080
    router.Run(":8080")
}



Bind方法是个好东西,它让我们处理json格式的request变得很方便,如上代码,只要我预先在struct里面打好json的标签或者form的标签,Bind方法会进行自动参数绑定。c.BindJSON(&myLogIn)这一步之后,参数值都会放到myLogIn这个对象的各个成员中去,接着就可以拿它去做事情了。注意Bind方法接受的都是指针参数。.Bind()会自动根据request中的content-type去自动推断是bind表单参数还是json的参数。


middleware中间件
中间件说简单点,就是自己可以定义一个函数,然后可以设置组或者单个,在组里的这些路由,或者单个路由,在去调用处理方法前,都会先去调用自己事先定义的函数。一般中间件主要用于用户登录校验。


总结

Gin是一个强大而好用的golang web框架。这里这里针对gin和其作者写的英文文档,做了翻译和加了些自己的理解,供大家和自己参考。


明天又是周一了,继续go go go!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值