Gin 是 go 语言开发的一个十分常用的框架,其可以支持和前端的直接交互,在搭建后端服务上是一个十分便捷的工具。本次项目开发就选择了 gin 框架作为基础框架,通过记录项目过程来进行 gin 框架的使用解析。
下载使用
下载并安装 gin:
go get -u github.com/gin-gonic.gin
使用样例演示
一个简单示例
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 创建一个默认的路由引擎
r := gin.Default()
// GET:请求方式;/hello:请求的路径
// 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数
r.GET("/hello", func(c *gin.Context) {
// c.JSON:返回JSON格式的数据
c.JSON(200, gin.H{
"message": "Hello world!",
})
})
// 启动HTTP服务,默认在0.0.0.0:8080启动服务
r.Run()
}
创建路由引擎
gin.Default() 用于创建路由。
RESTful API
使用不同的方法来对应 HTTP 协议的4个不同请求方法
GET用来获取资源POST用来新建资源PUT用来更新资源DELETE用来删除资源。
关于方法中的参数解析:
- 第一位为对应的路径,如上述中请求
/hello的路径为localhost:8080/hello. - 后续为执行的函数,可以多个,多个时排序在前的函数是用于状态判断的中间件。
启动服务
r.run() 用于启动服务,其中可以添加参数修改路由,比如 r.run(:9000) 则是对应路由地址 localhost:9000.
项目编写
main.go:
// ... 一些引包操作
func main() {
// 使用 gorm 的初始化,此处省略
err := initialize.InitDB()
if err != nil {
os.Exit(-1)
}
// gin 部分的框架搭建
r := gin.Default()
// 对 http 服务的搭建
initRouter(r)
r.Run()
}
router.go (路由相关):
func initRouter(r *gin.Engine) {
// public directory is used to serve static resources
r.Static("/static", "./public")
// 设置一个路由组
apiRouter := r.Group("/douyin")
// 导入中间件
auth := util.Jwt2r()
// 各个路径的搭建
apiRouter.GET("/feed/", controller.Feed)
apiRouter.GET("/user/", auth, controller.UserInfo)
apiRouter.POST("/user/register/", controller.Register)
apiRouter.POST("/user/login/", controller.Login)
apiRouter.POST("/publish/action/", auth, controller.Publish)
apiRouter.GET("/publish/list/", auth, controller.PublishList)
apiRouter.Use(auth)
{
apiRouter.POST("/favorite/action/", controller.FavoriteAction)
apiRouter.GET("/favorite/list/", controller.FavoriteList)
apiRouter.POST("/comment/action/", controller.CommentAction)
apiRouter.GET("/comment/list/", controller.CommentList)
apiRouter.POST("/relation/action/", controller.RelationAction)
apiRouter.GET("/relation/follow/list/", controller.FollowList)
apiRouter.GET("/relation/follower/list/", controller.FollowerList)
apiRouter.GET("/relation/friend/list/", controller.FriendList)
apiRouter.GET("/message/chat/", controller.MessageChat)
apiRouter.POST("/message/action/", controller.MessageAction)
}
}
下面对其中的技术进行详解。
设置文件资源路径
这里在本次项目编写的时候踩了好久的坑!
在极简抖音项目中,需要存放视频文件和封面图片。一开始没有仔细研究 demo, 懵逼了好久存放好的视频和封面为什么读取不到,原来是没理解资源设置的方式,其接口为:
func (group *RouterGroup) Static(relativePath string, root string) IRoutes
比如上述的 r.Static("/static", "./public") 即调用了这一结构体方法,声明文件存放的目录 root 在 ./public 这一个文件夹下,而在 http 运行时采用 localhost:8080/static 的路径可以调用这个文件夹里面的资源。
路由组
此处还设置了路由组,即
apiRouter := r.Group("/douyin")
此后 apiRouter 可以当成一个被 gin 搭建的普通框架使用,不同之处在于此时默认前缀路径为 localhost:8080/douyin.
中间件使用
抖音中很多服务都需要登录用户才能使用,而验证登录状态这件事其实都是有统一方式的。为了减小重复代码,可以采用中间件来实现对流程的统一控制,其必须是一个gin.HandlerFunc类型。上述的 util.Jwt2r() 就是一个中间件。
· 一般中间件的逻辑如下:
func middle(c *gin.Context) {
// Do something. 可能会在判断为不合规后就 return 不执行了
// 如果要执行业务逻辑
c.Next()
// 如果不要执行业务逻辑
c.Abort()
// ...
}
· 关于注册中间件:
-
全局注册:可以采用
Use()方法。r.Use(middle()) -
为某个路由单独注册,在注册路由时注册,可以注册多个:
r.GET("/test", middle(), func) -
为某个路由组注册,有两种方法:
// Type 1 apiGroup := r.Group("/douyin", middle()) { // ... } // Type 2 apiGroup := r.Group("/douyin", middle()) apiGroup.Use(middle()) { // ... }
总结
以上是本项目中路由设置的框架以及对应的 gin 框架指引。