feat(context): add BindQuery func (#1029)
* 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
This commit is contained in:
		
				
					committed by
					
						 Javier Provecho Fernandez
						Javier Provecho Fernandez
					
				
			
			
				
	
			
			
			
						parent
						
							74221b8a35
						
					
				
				
					commit
					c19aa0598b
				
			
							
								
								
									
										38
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								README.md
									
									
									
									
									
								
							| @ -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). | ||||
|  | ||||
|  | ||||
| @ -39,6 +39,7 @@ var ( | ||||
| 	JSON          = jsonBinding{} | ||||
| 	XML           = xmlBinding{} | ||||
| 	Form          = formBinding{} | ||||
| 	Query         = queryBinding{} | ||||
| 	FormPost      = formPostBinding{} | ||||
| 	FormMultipart = formMultipartBinding{} | ||||
| 	ProtoBuf      = protobufBinding{} | ||||
|  | ||||
| @ -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", | ||||
| @ -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) | ||||
|  | ||||
|  | ||||
							
								
								
									
										23
									
								
								binding/query.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								binding/query.go
									
									
									
									
									
										Normal file
									
								
							| @ -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) | ||||
| } | ||||
| @ -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. | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user