diff --git a/ctx.go b/ctx.go index acb1492a..b6578248 100644 --- a/ctx.go +++ b/ctx.go @@ -30,6 +30,8 @@ import ( // maxParams defines the maximum number of parameters per route. const maxParams = 30 +const queryTag = "query" + // Ctx represents the Context which hold the HTTP request and response. // It has methods for the request query string, parameters, body, HTTP headers and so on. type Ctx struct { @@ -725,7 +727,7 @@ func (c *Ctx) QueryParser(out interface{}) error { defer decoderPool.Put(decoder) // Set correct alias tag - decoder.SetAliasTag("query") + decoder.SetAliasTag(queryTag) data := make(map[string][]string) c.fasthttp.QueryArgs().VisitAll(func(key []byte, val []byte) { @@ -747,6 +749,7 @@ func (c *Ctx) QueryParser(out interface{}) error { func equalFieldType(out interface{}, kind reflect.Kind, key string) bool { // Get type of interface outTyp := reflect.TypeOf(out).Elem() + key = utils.ToLower(key) // Must be a struct to match a field if outTyp.Kind() != reflect.Struct { return false @@ -770,9 +773,11 @@ func equalFieldType(out interface{}, kind reflect.Kind, key string) bool { continue } // Get tag from field if exist - inputFieldName := typeField.Tag.Get(key) + inputFieldName := typeField.Tag.Get(queryTag) if inputFieldName == "" { inputFieldName = typeField.Name + } else { + inputFieldName = strings.Split(inputFieldName, ",")[0] } // Compare field/tag with provided key if utils.ToLower(inputFieldName) == key { diff --git a/ctx_test.go b/ctx_test.go index b920c686..8a08438b 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -2003,22 +2003,27 @@ func Test_Ctx_QueryParser(t *testing.T) { utils.AssertEqual(t, 0, len(empty.Hobby)) type Query2 struct { - ID int - Name string - Hobby string + ID int + Name string + Hobby string + FavouriteDrinks []string + Empty []string + No []int64 } - c.Request().URI().SetQueryString("id=1&name=tom&hobby=basketball,football") + c.Request().URI().SetQueryString("id=1&name=tom&hobby=basketball,football&favouriteDrinks=milo,coke,pepsi&empty=&no=1") q2 := new(Query2) utils.AssertEqual(t, nil, c.QueryParser(q2)) utils.AssertEqual(t, "basketball,football", q2.Hobby) + utils.AssertEqual(t, []string{"milo", "coke", "pepsi"}, q2.FavouriteDrinks) + utils.AssertEqual(t, []string{}, q2.Empty) + utils.AssertEqual(t, []int64{1}, q2.No) type RequiredQuery struct { Name string `query:"name,required"` } rq := new(RequiredQuery) c.Request().URI().SetQueryString("") - fmt.Println(c.QueryParser(rq)) utils.AssertEqual(t, "name is empty", c.QueryParser(rq).Error()) } @@ -2028,6 +2033,21 @@ func Test_Ctx_EqualFieldType(t *testing.T) { var dummy struct{ f string } utils.AssertEqual(t, false, equalFieldType(&dummy, reflect.String, "key")) + + var dummy2 struct{ f string } + utils.AssertEqual(t, false, equalFieldType(&dummy2, reflect.String, "f")) + + var user struct { + Name string + Address string `query:"address"` + Age int `query:"AGE"` + } + utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "name")) + utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "Name")) + utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "address")) + utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "Address")) + utils.AssertEqual(t, true, equalFieldType(&user, reflect.Int, "AGE")) + utils.AssertEqual(t, true, equalFieldType(&user, reflect.Int, "age")) } // go test -v -run=^$ -bench=Benchmark_Ctx_QueryParser -benchmem -count=4