diff --git a/context.go b/context.go index faa48133..759eccb4 100644 --- a/context.go +++ b/context.go @@ -647,6 +647,14 @@ func (c *Context) BindUri(obj any) error { return nil } +// BindUrl combines c.BindUri() and c.BindQuery(), abort with HTTP 400 likewise +func (c *Context) BindUrl(obj any) error { + if err := c.BindUri(obj); err != nil { + return err + } + return c.BindQuery(obj) +} + // MustBindWith binds the passed struct pointer using the specified binding engine. // It will abort the request with HTTP 400 if any error occurs. // See the binding package. @@ -704,6 +712,16 @@ func (c *Context) ShouldBindUri(obj any) error { return binding.Uri.BindUri(m, obj) } +// ShouldBindUrl combines c.ShouldBindQuery() and c.ShouldBindUri(). +// It will bind uri parameters and query part at the same time. +func (c *Context) ShouldBindUrl(obj any) error { + err := c.ShouldBindUri(obj) + if err != nil { + return err + } + return c.ShouldBindQuery(obj) +} + // ShouldBindWith binds the passed struct pointer using the specified binding engine. // See the binding package. func (c *Context) ShouldBindWith(obj any, b binding.Binding) error { diff --git a/githubapi_test.go b/githubapi_test.go index e74bddd5..871743b2 100644 --- a/githubapi_test.go +++ b/githubapi_test.go @@ -285,7 +285,7 @@ var githubAPI = []route{ {http.MethodDelete, "/user/keys/:id"}, } -func TestShouldBindUri(t *testing.T) { +func TestShouldBindUrl(t *testing.T) { DefaultWriter = os.Stdout router := New() @@ -294,20 +294,27 @@ func TestShouldBindUri(t *testing.T) { ID string `uri:"id" binding:"required"` } router.Handle(http.MethodGet, "/rest/:name/:id", func(c *Context) { - var person Person - assert.NoError(t, c.ShouldBindUri(&person)) + var person struct { + Person + Foo string `form:"foo"` + Bar string `form:"bar"` + } + assert.NoError(t, c.ShouldBindUrl(&person)) assert.True(t, "" != person.Name) assert.True(t, "" != person.ID) - c.String(http.StatusOK, "ShouldBindUri test OK") + assert.Equal(t, "foo", person.Bar) + assert.Equal(t, "bar", person.Foo) + c.String(http.StatusOK, "ShouldBindUrl test OK") }) path, _ := exampleFromPath("/rest/:name/:id") + path += "?foo=bar&bar=foo" w := PerformRequest(router, http.MethodGet, path) - assert.Equal(t, "ShouldBindUri test OK", w.Body.String()) + assert.Equal(t, "ShouldBindUrl test OK", w.Body.String()) assert.Equal(t, http.StatusOK, w.Code) } -func TestBindUri(t *testing.T) { +func TestBindUrl(t *testing.T) { DefaultWriter = os.Stdout router := New() @@ -316,20 +323,27 @@ func TestBindUri(t *testing.T) { ID string `uri:"id" binding:"required"` } router.Handle(http.MethodGet, "/rest/:name/:id", func(c *Context) { - var person Person - assert.NoError(t, c.BindUri(&person)) + var person struct { + Person + Foo string `form:"foo"` + Bar string `form:"bar"` + } + assert.NoError(t, c.BindUrl(&person)) assert.True(t, "" != person.Name) assert.True(t, "" != person.ID) - c.String(http.StatusOK, "BindUri test OK") + assert.Equal(t, "foo", person.Bar) + assert.Equal(t, "bar", person.Foo) + c.String(http.StatusOK, "BindUrl test OK") }) path, _ := exampleFromPath("/rest/:name/:id") + path += "?foo=bar&bar=foo" w := PerformRequest(router, http.MethodGet, path) - assert.Equal(t, "BindUri test OK", w.Body.String()) + assert.Equal(t, "BindUrl test OK", w.Body.String()) assert.Equal(t, http.StatusOK, w.Code) } -func TestBindUriError(t *testing.T) { +func TestBindUrlError(t *testing.T) { DefaultWriter = os.Stdout router := New() @@ -337,11 +351,16 @@ func TestBindUriError(t *testing.T) { Number string `uri:"num" binding:"required,uuid"` } router.Handle(http.MethodGet, "/new/rest/:num", func(c *Context) { - var m Member - assert.Error(t, c.BindUri(&m)) + var m struct { + Member + Foo string `form:"foo"` + } + assert.Error(t, c.BindUrl(&m)) + assert.True(t, "" == m.Foo) }) path1, _ := exampleFromPath("/new/rest/:num") + path1 += "?foo=bar" w1 := PerformRequest(router, http.MethodGet, path1) assert.Equal(t, http.StatusBadRequest, w1.Code) }