The source code
Post details
This is a little bit easier. We’ve done this many times before.
Register route:
v1.GET("/post/:id", controllers.GetPostDetailHandler)
Copy the code
Controller:
Func GetPostDetailHandler(c *gin.Context) {postIdStr := c.param ("id") postId, Err := strconv.ParseInt(postIdStr, 10, 64) // Check if err! = nil { zap.L().Error("GetPostDetailHandler", zap.Error(err)) ResponseError(c, CodeInvalidParam) return } data, err := logic.GetPostDetail(postId) if err ! = nil { zap.L().Error("GetPostDetailHandler", zap.Error(err)) ResponseError(c, CodeServerBusy) return } ResponseSuccess(c, data) }Copy the code
logic
func GetPostDetail(id int64) (model *models.Post, err error) {
return mysql.GetPostDetail(id)
}
Copy the code
The dao:
func GetPostDetail(id int64) (post *models.Post, err error) { post = new(models.Post) sqlStr := "select post_id,title,content,author_id,community_id,create_time,update_time " + " from post where post_id=?" err = db.Get(post, sqlStr, id) if err ! If err == sql.errnorows {zap.l ().warn ("no community ") err = nil}} return post, err}Copy the code
Look at the effect
Optimize the post details interface
There are some problems with the post interface. The main problem is that only the author ID and the block ID are returned
Let’s just modify it a little bit
Add a new structure:
type ApiPostDetail struct {
AuthorName string `json:"author_name"`
*Community `json:"_community"`
*Post `json:"_post"`
}
Copy the code
If we change our logic again, it will work:
Func GetPostDetail(id int64) (apiPostDetail *models.ApiPostDetail, err error) { Username, err := mysql.getUsernameById (post.authorID) if err! = nil {zap.l ().warn ("no author ") err = nil} community := GetCommunityById(post.CommunityId) if err! = nil { zap.L().Warn("no community ") err = nil } apiPostDetail = new(models.ApiPostDetail) apiPostDetail.AuthorName = username apiPostDetail.Community = community apiPostDetail.Post = post return apiPostDetail, err }Copy the code
Display a list of posts in pages
Paging queries are not too difficult, but the SQL statement side is slightly changed, and the Logic layer adds a for loop to concatenate our query results
v1.GET("/postlist", controllers.GetPostListHandler)
Copy the code
func GetPostListHandler(c *gin.Context) { pageSizeStr := c.Query("pageSize") pageNumStr := c.Query("pageNum") pageSize, err := strconv.ParseInt(pageSizeStr, 10, 64) if err ! = nil { ResponseError(c, CodeInvalidParam) return } pageNum, err := strconv.ParseInt(pageNumStr, 10, 64) if err ! = nil { ResponseError(c, CodeInvalidParam) return } if pageNum < 1 { ResponseErrorWithMsg(c, CodeInvalidParam, Return} data, err := logic.GetPostList(pageSize, pageNum) if err! = nil { zap.L().Error("GetPostDetailHandler", zap.Error(err)) ResponseError(c, CodeServerBusy) return } ResponseSuccess(c, data) }Copy the code
func GetPostList(pageSize int64, pageNum int64) (apiPostDetailList []*models.ApiPostDetail, err error) { var offset int64 offset = pageSize * (pageNum - 1) postList, err := mysql.GetPostList(offset, pageSize) if err ! = nil { return nil, err } apiPostDetailList = make([]*models.ApiPostDetail, 0, 2) for _, Username, err := mysql.getUsernameById (post.authorID) if err! = nil {ap.l ().warn ("no author ") err = nil return nil, err} err := GetCommunityById(post.CommunityId) if err ! = nil { zap.L().Warn("no community ") err = nil return nil, err } apiPostDetail := new(models.ApiPostDetail) apiPostDetail.AuthorName = username apiPostDetail.Community = community apiPostDetail.Post = post apiPostDetailList = append(apiPostDetailList, apiPostDetail) } return apiPostDetailList, nil }Copy the code
func GetPostList(offset int64, pageSize int64) (posts []*models.Post, err error) { zap.L().Info("GetPostList", zap.String("offset", strconv.FormatInt(offset, 10)), zap.String("pageSize", strconv.FormatInt(pageSize, 10))) sqlStr := "select post_id,title,content,author_id,community_id,create_time,update_time " + " from post limit ? That?" posts = make([]*models.Post, 0, pageSize) err = db.Select(&posts, sqlStr, offset, pageSize) if err ! = nil { return nil, err } return posts, err }Copy the code
Front ID distortion
The above code uses the snowflake algorithm to generate an INT64 ID, and in JSON we return a number instead of a string, which causes a problem. The maximum int64 value in GO is as follows:
max: 9223372036854775807
However, the front-end type treats the number as number and the maximum value is 2 to the power of 53 9007199254740992
Obviously this int64 is bigger than this value
In practice, the front end will have a loss of accuracy when it gets this number and parses it out.
So in general, as a server we are better off returning strings in JSON for ids.
The same is true of the value that the front end passes to us as a string, so it’s safest for the server to do the conversion itself when it gets the value
In go
All we have to do is tag the string where we set the tag
Of course, you can also define serialization and deserialization methods for your struct to solve this problem. But obviously it’s not as efficient as writing this tag