Skip to content

Commit 858270f

Browse files
kolaentevishr
authored andcommitted
Added feature to map url params to a struct with the default binder (#1165)
* Added feature to map url params to a struct with the default binder * Added test for mix of POST data and bound params * Renamed variables * Added error check * Removed unneded fix
1 parent 3136157 commit 858270f

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

bind.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ type (
3333
// Bind implements the `Binder#Bind` function.
3434
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
3535
req := c.Request()
36+
37+
paramNames := c.ParamNames()
38+
paramValues := c.ParamValues()
39+
params := make(map[string][]string)
40+
for i, name := range paramNames {
41+
params[name] = []string{paramValues[i]}
42+
}
43+
if err := b.bindData(i, params, "param"); err != nil {
44+
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
45+
}
46+
3647
if req.ContentLength == 0 {
3748
if req.Method == http.MethodGet || req.Method == http.MethodDelete {
3849
if err = b.bindData(i, c.QueryParams(), "query"); err != nil {

bind_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,56 @@ func TestBindbindData(t *testing.T) {
294294
assertBindTestStruct(assert, ts)
295295
}
296296

297+
func TestBindParam(t *testing.T) {
298+
e := New()
299+
req := httptest.NewRequest(GET, "/", nil)
300+
rec := httptest.NewRecorder()
301+
c := e.NewContext(req, rec)
302+
c.SetPath("/users/:id/:name")
303+
c.SetParamNames("id", "name")
304+
c.SetParamValues("1", "Jon Snow")
305+
306+
u := new(user)
307+
err := c.Bind(u)
308+
if assert.NoError(t, err) {
309+
assert.Equal(t, 1, u.ID)
310+
assert.Equal(t, "Jon Snow", u.Name)
311+
}
312+
313+
// Second test for the absence of a param
314+
c2 := e.NewContext(req, rec)
315+
c2.SetPath("/users/:id")
316+
c2.SetParamNames("id")
317+
c2.SetParamValues("1")
318+
319+
u = new(user)
320+
err = c2.Bind(u)
321+
if assert.NoError(t, err) {
322+
assert.Equal(t, 1, u.ID)
323+
assert.Equal(t, "", u.Name)
324+
}
325+
326+
// Bind something with param and post data payload
327+
body := bytes.NewBufferString(`{ "name": "Jon Snow" }`)
328+
e2 := New()
329+
req2 := httptest.NewRequest(POST, "/", body)
330+
req2.Header.Set(HeaderContentType, MIMEApplicationJSON)
331+
332+
rec2 := httptest.NewRecorder()
333+
334+
c3 := e2.NewContext(req2, rec2)
335+
c3.SetPath("/users/:id")
336+
c3.SetParamNames("id")
337+
c3.SetParamValues("1")
338+
339+
u = new(user)
340+
err = c3.Bind(u)
341+
if assert.NoError(t, err) {
342+
assert.Equal(t, 1, u.ID)
343+
assert.Equal(t, "Jon Snow", u.Name)
344+
}
345+
}
346+
297347
func TestBindUnmarshalTypeError(t *testing.T) {
298348
body := bytes.NewBufferString(`{ "id": "text" }`)
299349
e := New()

echo_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import (
1818

1919
type (
2020
user struct {
21-
ID int `json:"id" xml:"id" form:"id" query:"id"`
22-
Name string `json:"name" xml:"name" form:"name" query:"name"`
21+
ID int `json:"id" xml:"id" form:"id" query:"id" param:"id"`
22+
Name string `json:"name" xml:"name" form:"name" query:"name" param:"name"`
2323
}
2424
)
2525

0 commit comments

Comments
 (0)