Skip to content

Commit

Permalink
feat(context): add BindQuery func (#1029)
Browse files Browse the repository at this point in the history
* feat(context): add BindQuery func, only parse/bind the query string params.

* docs(readme): add BindQuery section.

* docs(readme): fix import.

* docs(readme): separate import
  • Loading branch information
easonlin404 authored and javierprovecho committed Jul 19, 2017
1 parent 74221b8 commit c19aa05
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 1 deletion.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,43 @@ func main() {
}
```

### Bind Query String
### Only Bind Query String

`BindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).

```go
package main

import (
"log"

"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 By Query String ======")
log.Println(person.Name)
log.Println(person.Address)
}
c.String(200, "Success")
}

```

### Bind Query String or Post Data

See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).

Expand Down
1 change: 1 addition & 0 deletions binding/binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
JSON = jsonBinding{}
XML = xmlBinding{}
Form = formBinding{}
Query = queryBinding{}
FormPost = formPostBinding{}
FormMultipart = formMultipartBinding{}
ProtoBuf = protobufBinding{}
Expand Down
27 changes: 27 additions & 0 deletions binding/binding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ func TestBindingForm2(t *testing.T) {
"", "")
}

func TestBindingQuery(t *testing.T) {
testQueryBinding(t, "POST",
"/?foo=bar&bar=foo", "/",
"foo=unused", "bar2=foo")
}

func TestBindingQuery2(t *testing.T) {
testQueryBinding(t, "GET",
"/?foo=bar&bar=foo", "/?bar2=foo",
"foo=unused", "")
}

func TestBindingXML(t *testing.T) {
testBodyBinding(t,
XML, "xml",
Expand Down Expand Up @@ -204,6 +216,21 @@ func testFormBinding(t *testing.T, method, path, badPath, body, badBody string)
assert.Error(t, err)
}

func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) {
b := Query
assert.Equal(t, b.Name(), "query")

obj := FooBarStruct{}
req := requestWithBody(method, path, body)
if method == "POST" {
req.Header.Add("Content-Type", MIMEPOSTForm)
}
err := b.Bind(req, &obj)
assert.NoError(t, err)
assert.Equal(t, obj.Foo, "bar")
assert.Equal(t, obj.Bar, "foo")
}

func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
assert.Equal(t, b.Name(), name)

Expand Down
23 changes: 23 additions & 0 deletions binding/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.

package binding

import (
"net/http"
)

type queryBinding struct{}

func (queryBinding) Name() string {
return "query"
}

func (queryBinding) Bind(req *http.Request, obj interface{}) error {
values := req.URL.Query()
if err := mapForm(obj, values); err != nil {
return err
}
return validate(obj)
}
5 changes: 5 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ func (c *Context) BindJSON(obj interface{}) error {
return c.MustBindWith(obj, binding.JSON)
}

// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query)
func (c *Context) BindQuery(obj interface{}) error {
return c.MustBindWith(obj, binding.Query)
}

// MustBindWith binds the passed struct pointer using the specified binding
// engine. It will abort the request with HTTP 400 if any error ocurrs.
// See the binding package.
Expand Down
16 changes: 16 additions & 0 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,22 @@ func TestContextBindWithJSON(t *testing.T) {
assert.Equal(t, w.Body.Len(), 0)
}

func TestContextBindWithQuery(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)

c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))

var obj struct {
Foo string `form:"foo"`
Bar string `form:"bar"`
}
assert.NoError(t, c.BindQuery(&obj))
assert.Equal(t, "foo", obj.Bar)
assert.Equal(t, "bar", obj.Foo)
assert.Equal(t, 0, w.Body.Len())
}

func TestContextBadAutoBind(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
Expand Down

0 comments on commit c19aa05

Please sign in to comment.