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