Skip to content

Commit

Permalink
Added feature to map url params to a struct with the default binder (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
kolaente authored and vishr committed Jun 21, 2019
1 parent 3136157 commit 858270f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
11 changes: 11 additions & 0 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ type (
// Bind implements the `Binder#Bind` function.
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
req := c.Request()

paramNames := c.ParamNames()
paramValues := c.ParamValues()
params := make(map[string][]string)
for i, name := range paramNames {
params[name] = []string{paramValues[i]}
}
if err := b.bindData(i, params, "param"); err != nil {
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
}

if req.ContentLength == 0 {
if req.Method == http.MethodGet || req.Method == http.MethodDelete {
if err = b.bindData(i, c.QueryParams(), "query"); err != nil {
Expand Down
50 changes: 50 additions & 0 deletions bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,56 @@ func TestBindbindData(t *testing.T) {
assertBindTestStruct(assert, ts)
}

func TestBindParam(t *testing.T) {
e := New()
req := httptest.NewRequest(GET, "/", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
c.SetPath("/users/:id/:name")
c.SetParamNames("id", "name")
c.SetParamValues("1", "Jon Snow")

u := new(user)
err := c.Bind(u)
if assert.NoError(t, err) {
assert.Equal(t, 1, u.ID)
assert.Equal(t, "Jon Snow", u.Name)
}

// Second test for the absence of a param
c2 := e.NewContext(req, rec)
c2.SetPath("/users/:id")
c2.SetParamNames("id")
c2.SetParamValues("1")

u = new(user)
err = c2.Bind(u)
if assert.NoError(t, err) {
assert.Equal(t, 1, u.ID)
assert.Equal(t, "", u.Name)
}

// Bind something with param and post data payload
body := bytes.NewBufferString(`{ "name": "Jon Snow" }`)
e2 := New()
req2 := httptest.NewRequest(POST, "/", body)
req2.Header.Set(HeaderContentType, MIMEApplicationJSON)

rec2 := httptest.NewRecorder()

c3 := e2.NewContext(req2, rec2)
c3.SetPath("/users/:id")
c3.SetParamNames("id")
c3.SetParamValues("1")

u = new(user)
err = c3.Bind(u)
if assert.NoError(t, err) {
assert.Equal(t, 1, u.ID)
assert.Equal(t, "Jon Snow", u.Name)
}
}

func TestBindUnmarshalTypeError(t *testing.T) {
body := bytes.NewBufferString(`{ "id": "text" }`)
e := New()
Expand Down
4 changes: 2 additions & 2 deletions echo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (

type (
user struct {
ID int `json:"id" xml:"id" form:"id" query:"id"`
Name string `json:"name" xml:"name" form:"name" query:"name"`
ID int `json:"id" xml:"id" form:"id" query:"id" param:"id"`
Name string `json:"name" xml:"name" form:"name" query:"name" param:"name"`
}
)

Expand Down

0 comments on commit 858270f

Please sign in to comment.