Skip to content

Commit

Permalink
<feat>(blog): add function for handling response and test
Browse files Browse the repository at this point in the history
- Added  pagination , covert  and app which process response result in JSON format and set sets the http status code.
- Added some test for  `global.Logger.SetTraceInfo` and `app.NewResponse(c).ToResponse`
- Added  a ping router name `test/ping`  to testing logger and ensure the service is alive. the router responds with a simple message .
- Replaced `interface` with `any` in some parts of the code.
 resolves issue  #12
  • Loading branch information
lc-1010 committed Jun 21, 2023
1 parent 95fb470 commit 42f1eb1
Show file tree
Hide file tree
Showing 10 changed files with 259 additions and 4 deletions.
21 changes: 21 additions & 0 deletions internal/routers/ping/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ping

import (
"blog-server/global"
"net/http"

"github.com/gin-gonic/gin"
)

type Ping struct{}

func NewPing() Ping {
return Ping{}
}
func (p *Ping) Pong(c *gin.Context) {
global.Logger.SetTraceInfo(c).Infof(c, "%s for test ping,path:%s", c.HandlerName(), c.Request.URL.Path)

c.JSON(http.StatusOK, map[string]string{
"msg": "pong",
})
}
9 changes: 9 additions & 0 deletions internal/routers/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package routers

import (
v1 "github.com/lc-1010/OneBlogService/internal/routers/api/v1"
"github.com/lc-1010/OneBlogService/internal/routers/ping"

"github.com/gin-gonic/gin"
)
Expand All @@ -13,6 +14,14 @@ func NewRouter() *gin.Engine {
r.Use(gin.Recovery())
article := v1.NewArticle()
tags := v1.NewTag()

ping := ping.NewPing()

p := r.Group("/test")
{
p.GET("/ping", ping.Pong)
}

apiv1 := r.Group("/api/v1")
{
//tags
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func setupDBEngine() error {
}

func setupLogger() error {
fileName := global.AppSetting.LogFileExt + "/" +
fileName := global.AppSetting.LogServePath + "/" +
global.AppSetting.LogFileName + global.AppSetting.LogFileExt
global.Logger = logger.NewLogger(&lumberjack.Logger{
Filename: fileName,
Expand Down
80 changes: 80 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package main

import (
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/go-playground/assert/v2"
"github.com/lc-1010/OneBlogService/global"
"github.com/lc-1010/OneBlogService/pkg/app"
)

func TestPing(t *testing.T) {
r := gin.Default()
r.GET("/ping", func(ctx *gin.Context) {
global.Logger.SetTraceInfo(ctx).Infof(ctx, "%s for test ping,path:%s", ctx.HandlerName(), ctx.Request.URL.Path)
ctx.JSON(http.StatusOK, gin.H{"message": "pong"})
})
r.Run()
}

func TestResponse(t *testing.T) {
r := gin.New()
r.GET("/test/ping", func(c *gin.Context) {
app.NewResponse(c).ToResponse(map[string]string{"msg": "ping pong is ok"})
})

req := httptest.NewRequest("GET", "/test/ping", nil)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = req
r.HandleContext(c)
assert.Equal(t, w.Code, http.StatusOK)

expcted := `{"msg":"ping pong is ok"}`
assert.Equal(t, w.Body.String(), expcted)

}
func TestMultiHandler(t *testing.T) {
r := gin.Default()

// 在路由中间件中设置消息
r.Use(func(c *gin.Context) {
c.Set("message", "Hello, world!")
c.Next()
})

// 注册一个路由,将多个处理函数关联到这个路由上
r.GET("/hello", func(c *gin.Context) {
// message := c.MustGet("message").(string)
// c.String(http.StatusOK, message)
// c.Set("message", message)
c.Next()
}, func(c *gin.Context) {
message := c.MustGet("message").(string)
c.String(http.StatusOK, message+" from world")
})

// 创建一个新的 HTTP 请求
req, err := http.NewRequest("GET", "/hello", nil)
if err != nil {
t.Fatal(err)
}

// 创建一个新的 HTTP 响应
w := httptest.NewRecorder()

// 发送 HTTP 请求到路由处理函数
r.ServeHTTP(w, req)

// 检查 HTTP 响应的状态码和内容
if w.Code != http.StatusOK {
t.Errorf("Unexpected status code %d", w.Code)
}
exp := "Hello, world! from world"
//msg := fmt.Sprintf("\nUnexpected body: %s", exp)
assert.Equal(t, w.Body.String(), exp)

}
51 changes: 51 additions & 0 deletions pkg/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 返回处理 c.JSON respone
// 内容列表整合 pagination
package app

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/lc-1010/OneBlogService/pkg/errcode"
)

type Response struct {
Ctx *gin.Context
}

type Pager struct {
Page int `json:"page,omitempty"`
PageSize int `json:"page_size,omitempty"`
TotalRows int `json:"total_rows,omitempty"`
}

func NewResponse(ctx *gin.Context) *Response {
return &Response{Ctx: ctx}
}

func (r *Response) ToResponse(data any) {
if data == nil {
data = gin.H{}
}
r.Ctx.JSON(http.StatusOK, data)
}

func (r *Response) ToResponseList(list any, totalRows int) {
r.Ctx.JSON(http.StatusOK, gin.H{
"list": list,
"pager": Pager{
Page: GetPage(r.Ctx),
PageSize: GetPageSize(r.Ctx),
TotalRows: totalRows,
},
})
}

func (r *Response) ToErrorResponse(err *errcode.Error) {
response := gin.H{"code": err.Code(), "msg": err.Msg()}
details := err.Details()
if len(details) > 0 {
response["details"] = details
}
r.Ctx.JSON(err.StatusCode(), response)
}
42 changes: 42 additions & 0 deletions pkg/app/pagination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 分页处理方法
// 页面数
package app

import (
"github.com/gin-gonic/gin"
"github.com/lc-1010/OneBlogService/convert"
"github.com/lc-1010/OneBlogService/global"
)

func GetPage(c *gin.Context) int {
page := convert.StrTo(c.Query("page")).MustInt()
if page <= 0 {
return 1
}
return page
}

func GetPageSize(c *gin.Context) int {
pageSize := convert.StrTo(c.Query("page_size")).MustInt()
if pageSize <= 0 {
return global.AppSetting.DefaultPageSize
}
if pageSize > global.AppSetting.MaxPageSize {
return global.AppSetting.MaxPageSize
}

return pageSize
}

func GetPageOffset(page, pageSize int) int {
reuslt := 0
if page > 0 {
reuslt = (page - 1) * pageSize
}

return reuslt
}

/************************************/
/*********** ***********/
/************************************/
29 changes: 29 additions & 0 deletions pkg/convert/convert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package convert

import "strconv"

type StrTo string

func (s StrTo) String() string {
return string(s)
}

func (s StrTo) Int() (int, error) {
v, err := strconv.Atoi(s.String())
return v, err
}

func (s StrTo) MustInt() int {
v, _ := s.Int()
return v
}

func (s StrTo) UInt32() (uint32, error) {
v, err := strconv.Atoi(s.String())
return uint32(v), err
}

func (s StrTo) MustUIn32() uint32 {
v, _ := s.UInt32()
return v
}
2 changes: 1 addition & 1 deletion pkg/errcode/common_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (e *Error) Msg() string {

}

func (e *Error) Msgf(args []interface{}) string {
func (e *Error) Msgf(args []any) string {
return fmt.Sprintf(e.msg, args...)
}

Expand Down
23 changes: 23 additions & 0 deletions pkg/logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/gin-gonic/gin"
"github.com/google/uuid"
)

type Level int8
Expand Down Expand Up @@ -125,6 +126,28 @@ func (l *Logger) WithTrace() *Logger {
return l
}

// SetTraceInfo 设置临时的trace id
func (l *Logger) SetTraceInfo(c *gin.Context) *Logger {
// header 中拿
traceID := c.Request.Header.Get("X-Trace-ID")
spanID := c.Request.Header.Get("X-Span-ID")
// 如果 X-Trace-ID 和 X-Span-ID 不存在,则生成新的值
if traceID == "" {
traceID = uuid.New().String()
c.Request.Header.Set("X-Trace-ID", traceID)

}
if spanID == "" {
spanID = uuid.New().String()
c.Request.Header.Set("X-Span-ID", spanID)

}
c.Set("X-Trace-ID", traceID)
c.Set("X-Span-ID", spanID)
l.WithContext(c)
return l
}

func (l *Logger) JSONFormat(level Level, message string) map[string]any {
data := make(Fields, len(l.fields)+4)
data["level"] = level.String()
Expand Down
4 changes: 2 additions & 2 deletions pkg/setting/section.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ type DatabaseSettingS struct {
MaxOpenConns int
}

var sections = make(map[string]interface{})
var sections = make(map[string]any)

func (s *Setting) ReadSection(k string, v interface{}) error {
func (s *Setting) ReadSection(k string, v any) error {
err := s.vp.UnmarshalKey(k, v)
if err != nil {
return err
Expand Down

0 comments on commit 42f1eb1

Please sign in to comment.