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 的模板渲染工具解决,小玖在后面的章节中详细介绍。

相关推荐
Rhys..20 分钟前
ES6是什么
前端·javascript·es6
Jammingpro1 小时前
【Vue专题】前端JS基础Part1(含模版字符串、解构赋值、变量常量与对象)
前端·javascript·vue.js
jiangzhihao05155 小时前
前端自动翻译插件webpack-auto-i18n-plugin的使用
前端·webpack·node.js
软件技术NINI7 小时前
html css网页制作成品——HTML+CSS盐津铺子网页设计(5页)附源码
前端·css·html
mapbar_front9 小时前
面试问题—我的问题问完了,你还有什么想问我的吗?
前端·面试
quweiie9 小时前
thinkphp8+layui多图上传,带删除\排序功能
前端·javascript·layui
李鸿耀9 小时前
React 项目 SVG 图标太难管?用这套自动化方案一键搞定!
前端
闲蛋小超人笑嘻嘻9 小时前
树形结构渲染 + 选择(Vue3 + ElementPlus)
前端·javascript·vue.js
叶梅树9 小时前
从零构建A股量化交易工具:基于Qlib的全栈系统指南
前端·后端·算法
巴博尔10 小时前
uniapp的IOS中首次进入,无网络问题
前端·javascript·ios·uni-app