package main
import "log"
import "github.com/gin-gonic/gin"
type Person struct {
Name string `json:"name"`
Address string `json:"address"`
}
func main() {
log.Println("Hello World")
route := gin.Default()
route.GET("/testing", startPage)
route.Run(":8085")
}
func startPage(c *gin.Context) {
var person Person
if c.BindJSON(&person) == nil {
log.Println(person.Name)
log.Println(person.Address)
log.Println("Binding success...............")
} else {
log.Println("Binding failed...............")
}
c.String(200, "Success")
}
The above code works only for curl -X GET localhost:8085/testing --data '{"name":"JJ", "address":"xyz"}' -H "Content-Type:application/json"
but not curl -X GET localhost:8085/testing?name=JJ&address=xyz -H "Content-Type:application/json"
if i use c.Bind(&person)
, binding failed both case.
How can i write the above code which binds both query string and json.
+1 for c.BindQuery
We don't need c.BindQuery
.
Try c.Bind
for query string and post data:
type Person struct {
Name string `form:"name"`
Address string `form:"address"`
}
Try c.BindJSON
for JSON data:
type Person struct {
Name string `json:"name"`
Address string `json:"address"`
}
Looking over the binding code, I don't see anywhere that it accesses req.URL.Query(). I don't understand how we can bind query parameters without that.
@jasonab it uses http.Request.Form, which contains query params.
@appleboy thanks! This is absolutely not clear from docs. :-(
@ei-grad Thanks, that was non-obvious :-)
The following example is working for me.
package main
import "log"
import "github.com/gin-gonic/gin"
type Person struct {
Name string `form:"name" json:"name"`
Address string `form:"address" json:"address"`
}
func main() {
route := gin.Default()
route.GET("/testing", startPage)
route.Run(":8085")
}
func startPage(c *gin.Context) {
var person Person
if c.Bind(&person) == nil {
log.Println("====== Bind By Query String ======")
log.Println(person.Name)
log.Println(person.Address)
}
if c.BindJSON(&person) == nil {
log.Println("====== Bind By JSON ======")
log.Println(person.Name)
log.Println(person.Address)
}
c.String(200, "Success")
}
And try the following command:
# bind by query
$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz"
# bind by json
$ curl -X GET localhost:8085/testing --data '{"name":"JJ", "address":"xyz"}' -H "Content-Type:application/json"
You can find the example from the following URL:
https://github.com/gin-gonic/gin#model-binding-and-validation
Maybe we need to add bind query example on documents. 馃槃
@jasonab @ei-grad I will update document asap.
Maybe we need to add bind query example on documents. 馃槃
It would be great.
What if you posted values and had query string params how would you only parse/bind the query string params.
Bind always uses r.Form which is a combination of posted values and query params...same goes for only wanting to parse/bind r.PostForm and not wanting query string.
+1 for BindQuery
@mehdy See the comment https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292
I make new PR to improve document. https://github.com/gin-gonic/gin/pull/772
So @appleboy if you posted data and had Query string params how could you ONLY bind the Query string params or ONLY bind posted data?
It seems like my previous comment was just overlooked.
https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292
Do you see the screenshot?
if c.Bind(&person) == nil {
log.Println("====== Bind By Query String ======")
log.Println(person.Name)
log.Println(person.Address)
}
if c.BindJSON(&person) == nil {
log.Println("====== Bind By JSON ======")
log.Println(person.Name)
log.Println(person.Address)
}
Yes @appleboy I did see the screenshot,
your example is for Query params and JSON and my example was posting Form Data and Query params.
What if someone wanted to ONLY bind the Query Params and not the form data.
that's exactly the point! I think we need an BindQuery
function that only binds the query params and not the post data in case some one is using both together
See PR https://github.com/gin-gonic/gin/pull/1029. Add c.BindQuery
function that only binds the query params and not the post data.
package main
import "log"
import "github.com/gin-gonic/gin"
type Person struct {
Name string `form:"name"`
Address string `form:"address"`
}
func main() {
route := gin.Default()
route.Any("/testing", startPage)
route.Run(":8085")
}
func startPage(c *gin.Context) {
var person Person
if c.BindQuery(&person) == nil {
log.Println("====== Only Bind Query String ======")
log.Println(person.Name)
log.Println(person.Address)
}
c.String(200, "Success")
}
Try the following command:
# only bind query
$ curl -X GET "localhost:8085/testing?name=eason&address=xyz"
# only bind query string, ignore form data
$ curl -X POST "localhost:8085/testing?name=eason&address=xyz" --data 'name=ignore&address=ignore' -H "Content-Type:application/x-www-form-urlencoded"
Will Output:
We don't need
c.BindQuery
.Try
c.Bind
for query string and post data:type Person struct { Name string `form:"name"` Address string `form:"address"` }
Try
c.BindJSON
for JSON data:type Person struct { Name string `json:"name"` Address string `json:"address"` }
bindQuery also works with "form" tag
Most helpful comment
The following example is working for me.
And try the following command:
You can find the example from the following URL:
https://github.com/gin-gonic/gin#model-binding-and-validation
Maybe we need to add bind query example on documents. 馃槃