gf icon indicating copy to clipboard operation
gf copied to clipboard

parameter name conflicts with tag `p` in Req struct when using SetParam

Open simplephp opened this issue 3 years ago • 2 comments

1. What version of Go and system type/arch are you using?

go version go1.18.7 windows/amd64

2. What version of GoFrame are you using?

v2.1.4

3. Can this issue be re-produced with the latest release?

yes

4. What did you do?

  1. 使用 gf init goframe-test 生成全新项目
  2. 在项目新建 $PROJECT_PATH/internal/logic/middleware/middleware.go 填充如下代码:
package middleware

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gctx"
	"goframe-test/internal/service"
	"strings"
)

type (
	sMiddleware struct{}
)

func init() {
	service.RegisterMiddleware(New())
}

func New() *sMiddleware {
	return &sMiddleware{}
}

func (s *sMiddleware) ApiValidation(r *ghttp.Request) {
	appversion := r.Request.Header.Get("appversion")
	headers := g.Map{
		"appversion":    appversion,
		"appintversion": 0,
	}
	rules := map[string]string{
		"appversion": "required|regex:^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$",
	}
	messages := map[string]interface{}{
		"appversion": map[string]string{
			"required": "平台数据不能为空",
			"regex":    "版本格式错误",
		},
	}
	err := g.Validator().Messages(messages).Rules(rules).Data(headers).Run(gctx.New())
	if err != nil {
		r.Response.WriteJsonExit(g.Map{
			`code`:    1000,
			`message`: err.FirstError(),
			`data`:    struct{}{},
		})
	}
	headers["appintversion"] = strings.Replace(appversion, ".", "", -1)
	r.SetParamMap(headers)
	r.Middleware.Next()
}
  1. gf gen service #gf 工具生成 service
  2. 在 $PROJECT_PATH/internal/cmd/cmd.go 添加中间件
package cmd

import (
	"context"
	"goframe-test/internal/service"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gcmd"

	"goframe-test/internal/controller"
)

var (
	Main = gcmd.Command{
		Name:  "main",
		Usage: "main",
		Brief: "start http server",
		Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
			s := g.Server()
			s.Use(service.Middleware().ApiValidation)
			s.Group("/", func(group *ghttp.RouterGroup) {
				group.Middleware(ghttp.MiddlewareHandlerResponse)
				group.Bind(
					controller.Hello,
				)
			})
			s.Run()
			return nil
		},
	}
)

  1. 在 $PROJECT_PATH/main.go 手动注册logic
package main

import (
	_ "goframe-test/internal/packed"

	_ "goframe-test/internal/logic"

	"github.com/gogf/gf/v2/os/gctx"

	"goframe-test/internal/cmd"
)

func main() {
	cmd.Main.Run(gctx.New())
}
  1. 修改$PROJECT_PATH/api/v1/hello.go
package v1

import (
	"github.com/gogf/gf/v2/frame/g"
)

type HelloReq struct {
	g.Meta     `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
	Appversion string `p:"appintversion" dc:"app版本"`
}
type HelloRes struct {
	g.Meta `mime:"text/html" example:"string"`
}
  1. 修改$PROJECT_PATH/internal/controller/hello.go
package controller

import (
	"context"

	"github.com/gogf/gf/v2/frame/g"

	"goframe-test/api/v1"
)

var (
	Hello = cHello{}
)

type cHello struct{}

func (c *cHello) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
	g.RequestFromCtx(ctx).Response.Writef("The Appversion value %s", req.Appversion)
	return
}

  1. 在postman中请求接口地址并在header中添加 Appversion 值为 1.0.2, 多请求几次输出结果不同 test-1 test-2

5. What did you expect to see?

期望输出:The Appversion value 102

6. What did you see instead?

The Appversion value 1.0.2/102 都可能会输出

simplephp avatar Oct 28 '22 04:10 simplephp

Appversion string `p:"appintversion" dc:"app版本"`
{
    "appversion":    "1.0.2",
    "appintversion": "102",
}

map遍历时,key顺序不是固定的,所以都有可能 字段名 和 p 标签 做成统一就好了 Appintversion string p:"appintversion" dc:"app版本"

sanrentai avatar Nov 10 '22 10:11 sanrentai

@sanrentai 就是这个原因,很容易踩坑,不过我看看能否改进下。

gqcn avatar Jan 18 '23 09:01 gqcn

2.7.0版本已经修复

wln32 avatar Apr 18 '24 05:04 wln32

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


Version 2.7.0 has been fixed

Issues-translate-bot avatar Apr 18 '24 05:04 Issues-translate-bot