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

相关推荐
To_OC3 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic3 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy3 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志4 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble5 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯5 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜6 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司6 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森7 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒8 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端