关于项目 gin 框架的简单使用实践 | 青训营

226 阅读3分钟

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 框架指引。