尝试地写了第一篇自己学习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章将向读者介绍使用模板整合视图层的技术。