sonic
sonic copied to clipboard
chore: migrate gin to hertz
描述
开发者您好, 我个人开发了一个将 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 = ¶m.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
}