sonic icon indicating copy to clipboard operation
sonic copied to clipboard

chore: migrate gin to hertz

Open Skyenought opened this issue 11 months ago • 0 comments

描述

开发者您好, 我个人开发了一个将 gin 转为 hertz 的 ast 工具, 并将其用于了该项目的改造(我注意到了TODO事项)

这个 PR 的大部分的改动都是普通的 API 替换, 但仍有少部分出于框架的差异进行了不得已的改动, 我会在后面有时间的时候再进行描述.

现提出这个 WIP PR 的作用是希望您能帮我看看修改后的 sonic 是否还能正常运行(其实我对她还没有那么熟悉), 麻烦了.

逻辑改动部分

  • 由于 app.RequestContext 并没有实现 context.Context interface, 所以通过在 middleware/log.go 中将 clientIP, userAgent 提前放入 ctx, 从而取出

https://github.com/go-sonic/sonic/blob/53db5562b4fb8da9b7a7be694233ff7bcff0b35b/util/gin.go#L13-L27

// middleware/log.go
func (g *GinLoggerMiddleware) LoggerWithConfig(conf GinLoggerConfig) app.HandlerFunc {
	return func(_ctx context.Context, ctx *app.RequestContext) {
		_ctx = context.WithValue(_ctx, "clientIP", ctx.ClientIP())
		_ctx = context.WithValue(_ctx, "userAgent", ctx.UserAgent())
		// Process request
		ctx.Next(_ctx)

	}
}

// util/gin.go
func GetClientIP(ctx context.Context) string {
	value, ok := ctx.Value("clientIP").(string)
	if !ok {
		return ""
	}
	return value
}

func GetUserAgent(ctx context.Context) string {
	value, ok := ctx.Value("userAgent").(string)
	if !ok {
		return ""
	}
	return value
}
  • hertz 目前不支持 gin 的 ShouldBindWith 的客制化方法, 例如将 ?status=public 通过先前的在 bind 时自定义序列化改为 uint, 所以暂使用 assert 方法再进行一次转换

https://github.com/go-sonic/sonic/blob/53db5562b4fb8da9b7a7be694233ff7bcff0b35b/handler/admin/comment_post.go#L46-L64

// handler/admin/comment_post.go

func (p *PostCommentHandler) ListPostComment(_ctx context.Context, ctx *app.RequestContext) (interface{}, error) {
	var commentQuery param.CommentQueryNoEnum
	err := ctx.BindAndValidate(&commentQuery)
	if err != nil {
		return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
	}
	commentQuery.Sort = &param.Sort{
		Fields: []string{"createTime,desc"},
	}
	comments, totalCount, err := p.PostCommentService.Page(_ctx, param.AssertCommentQuery(commentQuery), consts.CommentTypePost)
	
	return dto.NewPage(commentDTOs, totalCount, commentQuery.Page), nil
}

// model/param/comment.go
func AssertCommentQuery(t CommentQueryNoEnum) CommentQuery {
	str := t.CommentStatus
	res := CommentQuery{
		Page:      t.Page,
		Sort:      t.Sort,
		ContentID: t.ContentID,
		Keyword:   t.Keyword,
		ParentID:  t.ParentID,
	}
	switch str {
	case `"PUBLISHED"`:
		*res.CommentStatus = consts.CommentStatusPublished
	case `"AUDITING"`:
		*res.CommentStatus = consts.CommentStatusAuditing
	case `"RECYCLE"`:
		*res.CommentStatus = consts.CommentStatusRecycle
	}
	return res
}

Skyenought avatar Mar 21 '24 22:03 Skyenought