feat(bind): ShouldBindBodyWith shortcut and change doc (#3871)
* feat: ShouldBindBodyWith shortcut and change doc * fix: yaml can parse json test case * style: fix new test case in context_test.go * chore: modify the code style to specify binding type * chroe: gofmt modifies the code format
This commit is contained in:
parent
fd1faaded0
commit
7a865dcf1d
20
context.go
20
context.go
@ -774,6 +774,26 @@ func (c *Context) ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error
|
|||||||
return bb.BindBody(body, obj)
|
return bb.BindBody(body, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShouldBindBodyWithJSON is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
|
||||||
|
func (c *Context) ShouldBindBodyWithJSON(obj any) error {
|
||||||
|
return c.ShouldBindBodyWith(obj, binding.JSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldBindBodyWithXML is a shortcut for c.ShouldBindBodyWith(obj, binding.XML).
|
||||||
|
func (c *Context) ShouldBindBodyWithXML(obj any) error {
|
||||||
|
return c.ShouldBindBodyWith(obj, binding.XML)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldBindBodyWithYAML is a shortcut for c.ShouldBindBodyWith(obj, binding.YAML).
|
||||||
|
func (c *Context) ShouldBindBodyWithYAML(obj any) error {
|
||||||
|
return c.ShouldBindBodyWith(obj, binding.YAML)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldBindBodyWithTOML is a shortcut for c.ShouldBindBodyWith(obj, binding.TOML).
|
||||||
|
func (c *Context) ShouldBindBodyWithTOML(obj any) error {
|
||||||
|
return c.ShouldBindBodyWith(obj, binding.TOML)
|
||||||
|
}
|
||||||
|
|
||||||
// ClientIP implements one best effort algorithm to return the real client IP.
|
// ClientIP implements one best effort algorithm to return the real client IP.
|
||||||
// It calls c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
|
// It calls c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
|
||||||
// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
|
// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
|
||||||
|
257
context_test.go
257
context_test.go
@ -1977,6 +1977,263 @@ func TestContextShouldBindBodyWith(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContextShouldBindBodyWithJSON(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
bindingBody binding.BindingBody
|
||||||
|
body string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: " JSON & JSON-BODY ",
|
||||||
|
bindingBody: binding.JSON,
|
||||||
|
body: `{"foo":"FOO"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " JSON & XML-BODY ",
|
||||||
|
bindingBody: binding.XML,
|
||||||
|
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<root>
|
||||||
|
<foo>FOO</foo>
|
||||||
|
</root>`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " JSON & YAML-BODY ",
|
||||||
|
bindingBody: binding.YAML,
|
||||||
|
body: `foo: FOO`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " JSON & TOM-BODY ",
|
||||||
|
bindingBody: binding.TOML,
|
||||||
|
body: `foo=FOO`,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Logf("testing: %s", tt.name)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
|
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||||
|
|
||||||
|
type typeJSON struct {
|
||||||
|
Foo string `json:"foo" binding:"required"`
|
||||||
|
}
|
||||||
|
objJSON := typeJSON{}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.JSON {
|
||||||
|
assert.NoError(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||||
|
assert.Equal(t, typeJSON{"FOO"}, objJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.XML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||||
|
assert.Equal(t, typeJSON{}, objJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.YAML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||||
|
assert.Equal(t, typeJSON{}, objJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.TOML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||||
|
assert.Equal(t, typeJSON{}, objJSON)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextShouldBindBodyWithXML(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
bindingBody binding.BindingBody
|
||||||
|
body string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: " XML & JSON-BODY ",
|
||||||
|
bindingBody: binding.JSON,
|
||||||
|
body: `{"foo":"FOO"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " XML & XML-BODY ",
|
||||||
|
bindingBody: binding.XML,
|
||||||
|
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<root>
|
||||||
|
<foo>FOO</foo>
|
||||||
|
</root>`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " XML & YAML-BODY ",
|
||||||
|
bindingBody: binding.YAML,
|
||||||
|
body: `foo: FOO`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " XML & TOM-BODY ",
|
||||||
|
bindingBody: binding.TOML,
|
||||||
|
body: `foo=FOO`,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Logf("testing: %s", tt.name)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
|
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||||
|
|
||||||
|
type typeXML struct {
|
||||||
|
Foo string `xml:"foo" binding:"required"`
|
||||||
|
}
|
||||||
|
objXML := typeXML{}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.JSON {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
|
||||||
|
assert.Equal(t, typeXML{}, objXML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.XML {
|
||||||
|
assert.NoError(t, c.ShouldBindBodyWithXML(&objXML))
|
||||||
|
assert.Equal(t, typeXML{"FOO"}, objXML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.YAML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
|
||||||
|
assert.Equal(t, typeXML{}, objXML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.TOML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
|
||||||
|
assert.Equal(t, typeXML{}, objXML)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextShouldBindBodyWithYAML(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
bindingBody binding.BindingBody
|
||||||
|
body string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: " YAML & JSON-BODY ",
|
||||||
|
bindingBody: binding.JSON,
|
||||||
|
body: `{"foo":"FOO"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " YAML & XML-BODY ",
|
||||||
|
bindingBody: binding.XML,
|
||||||
|
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<root>
|
||||||
|
<foo>FOO</foo>
|
||||||
|
</root>`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " YAML & YAML-BODY ",
|
||||||
|
bindingBody: binding.YAML,
|
||||||
|
body: `foo: FOO`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " YAML & TOM-BODY ",
|
||||||
|
bindingBody: binding.TOML,
|
||||||
|
body: `foo=FOO`,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Logf("testing: %s", tt.name)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
|
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||||
|
|
||||||
|
type typeYAML struct {
|
||||||
|
Foo string `yaml:"foo" binding:"required"`
|
||||||
|
}
|
||||||
|
objYAML := typeYAML{}
|
||||||
|
|
||||||
|
// YAML belongs to a super collection of JSON, so JSON can be parsed by YAML
|
||||||
|
if tt.bindingBody == binding.JSON {
|
||||||
|
assert.NoError(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||||
|
assert.Equal(t, typeYAML{"FOO"}, objYAML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.XML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||||
|
assert.Equal(t, typeYAML{}, objYAML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.YAML {
|
||||||
|
assert.NoError(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||||
|
assert.Equal(t, typeYAML{"FOO"}, objYAML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.TOML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||||
|
assert.Equal(t, typeYAML{}, objYAML)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextShouldBindBodyWithTOML(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
bindingBody binding.BindingBody
|
||||||
|
body string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: " TOML & JSON-BODY ",
|
||||||
|
bindingBody: binding.JSON,
|
||||||
|
body: `{"foo":"FOO"}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " TOML & XML-BODY ",
|
||||||
|
bindingBody: binding.XML,
|
||||||
|
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<root>
|
||||||
|
<foo>FOO</foo>
|
||||||
|
</root>`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " TOML & YAML-BODY ",
|
||||||
|
bindingBody: binding.YAML,
|
||||||
|
body: `foo: FOO`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: " TOML & TOM-BODY ",
|
||||||
|
bindingBody: binding.TOML,
|
||||||
|
body: `foo = 'FOO'`,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Logf("testing: %s", tt.name)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
c, _ := CreateTestContext(w)
|
||||||
|
|
||||||
|
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||||
|
|
||||||
|
type typeTOML struct {
|
||||||
|
Foo string `toml:"foo" binding:"required"`
|
||||||
|
}
|
||||||
|
objTOML := typeTOML{}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.JSON {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||||
|
assert.Equal(t, typeTOML{}, objTOML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.XML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||||
|
assert.Equal(t, typeTOML{}, objTOML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.YAML {
|
||||||
|
assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||||
|
assert.Equal(t, typeTOML{}, objTOML)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.bindingBody == binding.TOML {
|
||||||
|
assert.NoError(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||||
|
assert.Equal(t, typeTOML{"FOO"}, objTOML)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContextGolangContext(t *testing.T) {
|
func TestContextGolangContext(t *testing.T) {
|
||||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
|
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
|
||||||
|
@ -1956,7 +1956,12 @@ func SomeHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For this, you can use `c.ShouldBindBodyWith`.
|
For this, you can use `c.ShouldBindBodyWith` or shortcuts.
|
||||||
|
|
||||||
|
- `c.ShouldBindBodyWithJSON` is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
|
||||||
|
- `c.ShouldBindBodyWithXML` is a shortcut for c.ShouldBindBodyWith(obj, binding.XML).
|
||||||
|
- `c.ShouldBindBodyWithYAML` is a shortcut for c.ShouldBindBodyWith(obj, binding.YAML).
|
||||||
|
- `c.ShouldBindBodyWithTOML` is a shortcut for c.ShouldBindBodyWith(obj, binding.TOML).
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func SomeHandler(c *gin.Context) {
|
func SomeHandler(c *gin.Context) {
|
||||||
@ -1969,7 +1974,7 @@ func SomeHandler(c *gin.Context) {
|
|||||||
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
|
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
|
||||||
c.String(http.StatusOK, `the body should be formB JSON`)
|
c.String(http.StatusOK, `the body should be formB JSON`)
|
||||||
// And it can accepts other formats
|
// And it can accepts other formats
|
||||||
} else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
|
} else if errB2 := c.ShouldBindBodyWithXML(&objB); errB2 == nil {
|
||||||
c.String(http.StatusOK, `the body should be formB XML`)
|
c.String(http.StatusOK, `the body should be formB XML`)
|
||||||
} else {
|
} else {
|
||||||
...
|
...
|
||||||
|
Loading…
Reference in New Issue
Block a user