GO 的 Web 开发系列(三)—— 通过 Gin 实现 Html 模板和 Api 接口路由

Gin 的路由其实就是 Java 中 @RequestMapping 注解的内容,只是 Go 需要在一个代码模块中统一对所有路由进行配置。

全文链接:https://blog.nineya.com/archives/150.html

一、路由组配置

一般情况下,通过路由需要完成两个事情,一是通过 HTML 模板完成前端页面的渲染,二是实现 Api 接口调用。

这两部分功能是完全不一样的,在 Gin 中可以用两个不同的路由组来隔离逻辑。

go 复制代码
router := gin.Default()
// 指定模板文件所在的路径
router.LoadHTMLGlob("templates/*.html")
// 渲染html的路由组
htmlGroup := router.Group("")
// api 处理的路由组
apiGroup := router.Group("api")

再更近一步,可以将 API 路由组再细分为公共 API 和私有 API。

go 复制代码
// 公共API路由组
publicGroup := apiGroup.Group("public")
// 私有API路由组,绑定鉴权中间件
privateGroup := apiGroup.Group("")
privateGroup.Use(middleware.AdminAuth)

二、API 接口实现

创建一个简单的 GET 接口,并返回一条字符串数据内容。

go 复制代码
apiGroup.GET("/health", func(c *gin.Context) {
	c.String(200, "ok health")
})

返回一个 JSON 数据:

go 复制代码
apiGroup.GET("/health", func(c *gin.Context) {
	c.AbortWithStatusJSON(200, map[string]string{"msg": "ok health"})
})

三、HTML 模板渲染

渲染模板用的是 Go 内置的 html.template 工具包,Gin 对该工具包进行了集成,在渲染 Html 模板前需要先在 *gin.Engine 路由上指定模板文件所在的位置。

必须在 *gin.Engine 路由上指定,不能在路由组上指定。

有两个方法可以指定模板位置:

router.LoadHTMLGlob 函数可以指定一个路径,模糊匹配下的模板文件。

go 复制代码
// 指定模板所在的目录
router.LoadHTMLGlob("templates/*")
// 指定模板文件为html文件
router.LoadHTMLGlob("templates/*.html")
// 当模板在多级目录下时
router.LoadHTMLGlob("templates/**/*.html")

router.LoadHTMLFiles 函数用于直接指定模板文件名称,可以同时指定多个文件。

go 复制代码
router.LoadHTMLFiles("templates/index.html", "templates/page/index.html")

模板接口:

通过如下方法就可以指定渲染模板。

go 复制代码
htmlGroup.GET("/index.html", func(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", gin.H{
		"title": "玖涯菜菜子",
	})
})

四、HTML 模板的缺陷

通过章节三的方法可以实现模板,但是这个方法是存在一些问题的,或者说是存在一些限制。因为 Gin 只是简单集成了这个模板框架,并没有怎么考虑一些细节问题。

4.1 模板访问问题

注册了 templates/page/index.html 模板,但是通过 templates/page/index.html 或者 page/index.html 会发现访问不到模板,只能通过 index.html 访问。

原因: 在注册模板时以文件名作为模板名称,所以c.HTML函数中只要模板文件名,不带模板所在的目录。如果不同目录出现多个同名文件,模板将相互覆盖。

如上例子中,router.LoadHTMLFiles("templates/index.html", "templates/page/index.html") 这两个文件中,templates/index.html 文件会被覆盖的。

解决方法: 在模板中通过 define 关键字为模板中的代码片断赋予一个新名称,然后通过这个名称访问模板。

go 复制代码
{{ define "test/index.html" }}
test
{{ end }}
4.2 多次注册模板只有最后一次注册能生效

执行了多次 router.LoadHTMLGlobrouter.LoadHTMLFiles 函数,只有最后一次注册的内容能够生效。

原因: 每执行一次上面的方法都会重置 Gin 的 HTMLRender 属性,而这个属性存储着模板信息,所以每一次调这个函数都会重置模板状态。

解决方法: 通过官方接口无法解决,需要自己继承 HTMLRender 写一个 HTML 渲染的接口实现,在一个章节细说。

4.3 LoadHTMLGlob 指定多级目录会报错

原因: 使用 **/* 这种方式指定了两级目录,如果不存在两级目录,程序运行将会出错。

解决方法: 通过官方的接口无法解决,可自己继承 HTMLRender 写一个 HTML 渲染的接口解决。

以上问题可通过继承 HTMLRender 自定义 Gin 的模板渲染工具解决,小玖在后面的章节中详细介绍。

相关推荐
modelmd9 分钟前
Go 编程语言指南 练习题目分享
开发语言·学习·golang
Nan_Shu_61413 分钟前
学习: Threejs (2)
前端·javascript·学习
G_G#21 分钟前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界37 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路1 小时前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug1 小时前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121381 小时前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架