本文主要是介绍19.创建帖子,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 一、建立路由
- 二、开发CreatePostHandler
- 三、编写logic
- 四、编写dao层
- 五、编译测试运行
一、建立路由
这里要稍微注意的是:需要登录后才可以发表帖子,所以需要用到我们之前写的鉴权中间件。中间件对用户携带的token
解析成功后,便会将用户信息存入ctx
中,我们如果从ctx
中能取出用户信息,说明鉴权成功,否则失败。
router/route.go
// 需要登录后才可以发表帖子,所以需要鉴权中间件v1.POST("/post", middlewares.JWTAuthMiddleware(), controller.CreatePostHandler)
为了文档看起来更清晰,我这里将中间件的代码和从ctx
中获取用户id
的方法再贴一下。
middlewares/auth.go
package middlewaresimport ("bluebell/constdef""bluebell/controller""bluebell/pkg/jwt""strings""github.com/gin-gonic/gin"
)// JWTAuthMiddleware 基于JWT的认证中间件
func JWTAuthMiddleware() func(c *gin.Context) {return func(c *gin.Context) {// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI// 这里假设Token放在Header的Authorization中,并使用Bearer开头// Authorization: Bearer xxxxxxx.xxx.xxx / X-TOKEN: xxx.xxx.xx// 这里的具体实现方式要依据你的实际业务情况决定,和前端对其即可authHeader := c.Request.Header.Get("Authorization")if authHeader == "" {controller.ResponseError(c, controller.CodeNeedLogin)c.Abort()return}// 按空格分割parts := strings.SplitN(authHeader, " ", 2)if !(len(parts) == 2 && parts[0] == "Bearer") {controller.ResponseError(c, controller.CodeInvalidToken)c.Abort()return}// parts[1]是获取到的tokenString,我们使用之前定义好的解析JWT的函数来解析它mc, err := jwt.ParseToken(parts[1])if err != nil {controller.ResponseError(c, controller.CodeInvalidToken)c.Abort()return}// 将当前请求的userId信息保存到请求的上下文c上c.Set(constdef.CtxUserIDKey, mc.UserID)c.Next() // 后续的处理请求的函数中 可以用过c.Get(CtxUserIDKey) 来获取当前请求的用户信息}
}
controller/request.go
package controllerimport ("bluebell/constdef""errors""strconv""github.com/gin-gonic/gin"
)var ErrorUserNotLogin = errors.New("用户未登录")// getCurrentUserID 获取当前登录的用户ID
func getCurrentUserID(c *gin.Context) (userID int64, err error) {uid, ok := c.Get(constdef.CtxUserIDKey)if !ok {err = ErrorUserNotLoginreturn}userID, ok = uid.(int64)if !ok {err = ErrorUserNotLoginreturn}return
}
二、开发CreatePostHandler
controller/post.go
// CreatePostHandler 创建帖子的处理函数
func CreatePostHandler(c *gin.Context) {// 1. 获取参数及参数的校验//c.ShouldBindJSON() // validator --> binding tagp := new(models.Post)if err := c.ShouldBindJSON(p); err != nil {zap.L().Debug("c.ShouldBindJSON(p) error", zap.Any("err", err))zap.L().Error("create post with invalid param")ResponseError(c, CodeInvalidParam)return}// 从 c 取到当前发请求的用户的IDuserID, err := getCurrentUserID(c)if err != nil {ResponseError(c, CodeNeedLogin)return}p.AuthorId = userID// 2. 创建帖子if err := logic.CreatePost(p); err != nil {zap.L().Error("logic.CreatePost(p) failed", zap.Error(err))ResponseError(c, CodeServerBusy)return}// 3. 返回响应ResponseSuccess(c, nil)
}
三、编写logic
logic/post.go
package logicimport ("bluebell/dao/mysql""bluebell/models""go.uber.org/zap"
)func CreatePost(post *models.Post) error {// 1. 使用雪花算法生成post idpost.PostId = snowflake.GenID()// 2. 保存到数据库中err := mysql.CreatePost(post)if err != nil {return err}return nil
}
四、编写dao层
mysql/post.go:增加获取帖子详情函数
func CreatePost(post *models.Post) error {return db.Create(&post).Error
}
五、编译测试运行
可以看到是创建成功的
这篇关于19.创建帖子的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!