课后实践
- 支持对话题发布回帖。
- 回帖id生成需要保证不重复、唯一性。
- 新加回帖追加到本地文件,同时需要更新索引,注意Map的并发安全问题 。
发帖回帖流程都是一样的,就写了发帖
//server.go
func main() {
if err := Init("./data/"); err != nil {
os.Exit(-1)
}
r := gin.Default()
r.GET("/community/page/get/:id", func(c *gin.Context) {
topicId := c.Param("id")
data := cotroller.QueryPageInfo(topicId)
c.JSON(200, data)
})
//发帖
r.GET("/community/page/publish", func(c *gin.Context) {
title := c.Query("title")
content := c.Query("content")
data := cotroller.PublishTopic(title, content)
c.JSON(200, data)
})
//end
err := r.Run(":8080")
if err != nil {
return
}
}
//controller层
func PublishTopic(title string, content string) *PageData {
service.PublishTopic(title, content)
return &PageData{Code: 200, Msg: "success"}
}
//service层
func PublishTopic(title string, content string) {
repository.InsertTopic(title, content)
}
//dao层
func InsertTopic(title string, content string) {
lock.Lock()
topicIdx++ //自增id
topic := Topic{topicIdx, title, content, time.Now().Unix()}
topicIndexMap[topicIdx] = &topic //更新索引
data, err := json.Marshal(&topic)
if err != nil {
return
}
f, err := os.OpenFile("./data/topic", os.O_WRONLY|os.O_APPEND, 0666) //追加写入文件
defer f.Close()
if err != nil {
return
}
f.WriteString("\n")
f.Write(data)
lock.Unlock()
}
本来更新索引应该写到service层的,但是它的repository放的map用的小写是包私有的,基于开闭原则我也不想改源代码,id是在repository这个包里增加了两个idx变量方便自增id,因为它给的数据结构的id是int,其他算法也用不上,map的并发问题就用lock解决吧,目前没考虑性能的东西,就纯粹熟悉了一下gin这个框架,看了一下gin的文档
测试用的apipost