尝试地写了第一篇自己学习Go Web框架的感受和入门的文章,发现反响还不错,大家也提出了很多的问题来一起交流。近期也渐渐地出现了很多有关go语言开发的相关文章,包括有在蚂蚁金服的大牛的分享,我也一直有在看博客园和学习,这里越来越多人的去学习和使用Go,感觉也是非常好的趋势。希望和大家一起来继续学习。

Gin路由

本章概要

  • 路由(Router)介绍
  • Handler(处理器)介绍

 

2.1 路由(Router)介绍

        路由是一个非常重要的概念,所有的接口都要有路由来进行管理。虽然传统的J2EE(通过Spring框架)和.Net(ABP框架)通过注解已经将这个概念给弱化了,但是无论是Python(Django)和PHP(Laravel)都还是非常强调路由的重要性的。所有的接口都必须通过路由来指向,现在包括很多的前端框架如React和Vue也都已经添加这个路由的方式。Gin的路由是基于httprouter进行开发,有非常好的性能和表现力。

2.1.1 使用路由的示例

Gin的路由支持GET , POST , PUT , DELETE , PATCH , HEAD , OPTIONS 请求,同时还有一个 Any 函数,可以同时支持以上的所有请求。(分别对应SpringMvc框架中的@GetMapping, @PostMapping, @PutMapping, @DeleteMapping,@PatchMapping,无,无和@RequestMapping注解),其使用方式大同小异,我们可以通过以下代码添加对应的路由:

// 添加 Get 请求路由
engine.GET("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin get method")
})
// 添加 Post 请求路由
engine.POST("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin post method")
})
// 添加 Put 请求路由
engine.PUT("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin put method")
})
// 添加 Delete 请求路由
engine.DELETE("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin delete method")
})
// 添加 Patch 请求路由
engine.PATCH("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin patch method")
})
// 添加 Head 请求路由
engine.HEAD("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin head method")
})
// 添加 Options 请求路由
engine.OPTIONS("/", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin options method")
})
// 添加处理任意方法的请求路由
engine.Any("/hello", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin any method")
})
// 使用Handle方法添加 Get 请求路由
engine.Handle("GET", "/ping", func(context *gin.Context) {
    context.String(http.StatusOK, "hello gin handle get method")
})

以上接口大家启动应用后可以在浏览器和Postman等工具进行尝试。

2.1.2 获取各种参数

1. 获取Query参数(url参数)

Gin中使用Query方法获取url参数:

engine.GET("/user", func(context *gin.Context) {
    name := context.Query("name")
    context.String(http.StatusOK, "hello " + name)
})

运行后在浏览器中访问 “http://localhost:8080/user?name=itachizhu" 就可以看到相关的结果了。

2. 获取Form表单参数

Gin中使用PostForm获取表单参数(Content-Type=application/x-www-form-urlencoded),使用FormFile获取表单提交的文件参数(Content-Type=multipart/form-data)

engine.POST("/user", func(context *gin.Context) {
    name := context.PostForm("name")
    context.String(http.StatusOK, "hello " + name)
})

运行后在Postman工具中访问相关的接口后可以看到相关的结果。

3. 获取请求Body中json串

Gin中使用BindJSON方法可以将请求中的json数据反序列化为对象或者map和slice(Content-Type=application/json)

engine.PUT("/user", func(context *gin.Context) {
    var m map[string]string
    if err := context.BindJSON(&m); err != nil {
        context.String(http.StatusInternalServerError, "error data!")
        return
    }
    context.String(http.StatusOK, "hello " + m["name"])
})

运行后在Postman工具中访问相关的接口后可以看到相关的结果。

4. 获取路劲参数

Gin中使用Param方法获取路径参数:

engine.GET("/user/:name", func(context *gin.Context) {
    name := context.Param("name")
    context.String(http.StatusOK, "hello " + name)
})

运行后在浏览器中访问 “http://localhost:8080/user/itachizhu" 就可以看到相关的结果了。

2.1.3 路由分组

Gin可以将请求路径前面相同归并为组的概念(就和在SpringMVC的Controller类中注解@RequestMapping中添加公共路径是一样的)

admin := engine.Group("/admin")
{
    admin.Any("/hello", func(context *gin.Context) {
        context.String(http.StatusOK, "hello we are admin group!")
    })
}

本节代码地址  

2.2 Handler(处理器)介绍

        经过上面简单的例子的演示和操作,现在我们大概可以了解到路由需要传入两个参数,一个为路径,另一个为路由执行的方法,我们叫做它处理器 Handler(在J2EE中我们通过叫它Action或者Controller),而且,该参数是可变长参数。也就是说,可以传入多个 handler,形成一条 handler chain 。同时对 handler 该函数有着一些要求,该函数需要传入一个 Gin.Context 指针,同时要通过该指针进行值得处理。Handler 函数可以对前端返回 字符串,Json,Html 等多种格式或形式文件,之后我们会慢慢逐一介绍。

        因为Go本身支持函数式编程,所以很多就直接用匿名函数方式直接作为参数传入方法中去了。在真正的编程中,我们也通常会将它抽象成mvc模式,由另外的包方法中进行承载。

        下面我们就用已学到知识,先将Gin进行Router(路由)和Controller(控制器)的抽象,渐渐形成和其他语言框架那样的MVC模式。

        项目结构入如图2-1所示:

        图2-1

本节代码地址

 

2.3 小结

        本章主要向读者介绍了Gin的路由和处理器,通过简单的路由的使用,基本明白了路由在 Gin 中的地位,也对一些常见的使用方式有了一些直观的认识。并且能够使用面向对象的思维将路由和处理器抽象成MVC模式。第3章将向读者介绍使用模板整合视图层的技术。

08-18 21:28