gin-gonic / gin

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
https://gin-gonic.com/
MIT License
78.25k stars 7.99k forks source link

Map as query parameter suuport Bind #2606

Open hyzgh opened 3 years ago

hyzgh commented 3 years ago

Description

I want to use a struct to bind map query parameter, it seems that gin doesn't support it yet.

How to reproduce

Run server:

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
)

type Req struct {
    Ext map[string]string `form:"ext"`
}

func main() {
    r := gin.Default()
    r.GET("/map", func(c *gin.Context) {
        ext := c.QueryMap("ext")
        fmt.Println(ext)
        // output: map[foo:bar]

        f := Req{}
        err := c.BindQuery(&f)
        if err != nil {
            c.Status(500)
        }
        fmt.Println(f)
        // actual output: { map[]}
        // expected output: { map[foo:bar]}
        c.Status(200)
    })

    r.Run(":8082")
}

Curl:

curl --location -g --request GET 'localhost:8082/map?ext[foo]=bar'

Environment

Doarakko commented 3 years ago

It seems that it will be supported in v1.7 https://github.com/gin-gonic/gin/pull/2484

hyzgh commented 3 years ago

@Doarakko Thank you for pointing that out. I update my gin dependency to the latest, but it still doesn't work. I think what that MR solves is to bind a map, as I need to bind a struct with a map embedded. It's different.

Doarakko commented 3 years ago

@hyzgh Thank you and sorry for the misunderstanding.

dreamer2q commented 3 years ago

mark: this feature is still not suppoted by gin.

dreamer2q commented 3 years ago

Somehow, the *gin.Context provides a method called QueryMap, you can use it to do your own mapping.

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
)

type Req struct {
    Ext map[string]string `form:"ext"`
}

func main() {
    r := gin.Default()
    r.GET("/map", func(c *gin.Context) {
        ext := c.QueryMap("ext")
        fmt.Println(ext)
        // output: map[foo:bar]

        f := Req{}
               // Take notice of this sentence
        f.Ext = c.QueryMap("Ext")
        fmt.Println(f)
        c.Status(200)
    })

    r.Run(":8082")
}
shaicantor commented 1 year ago

any update regarding this?