feat: support json array in request body (#4444)

This commit is contained in:
Kevin Wan 2024-11-05 22:09:30 +08:00 committed by GitHub
parent 1940f7bd58
commit 53a74759a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 9 deletions

View File

@ -3,6 +3,7 @@ package httpx
import (
"io"
"net/http"
"reflect"
"strings"
"sync/atomic"
@ -43,16 +44,19 @@ type Validator interface {
// Parse parses the request.
func Parse(r *http.Request, v any) error {
if err := ParsePath(r, v); err != nil {
return err
}
kind := mapping.Deref(reflect.TypeOf(v)).Kind()
if kind != reflect.Array && kind != reflect.Slice {
if err := ParsePath(r, v); err != nil {
return err
}
if err := ParseForm(r, v); err != nil {
return err
}
if err := ParseForm(r, v); err != nil {
return err
}
if err := ParseHeaders(r, v); err != nil {
return err
if err := ParseHeaders(r, v); err != nil {
return err
}
}
if err := ParseJsonBody(r, v); err != nil {

View File

@ -325,11 +325,31 @@ func TestParseJsonBody(t *testing.T) {
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body))
r.Header.Set(ContentType, header.JsonContentType)
assert.NoError(t, ParseJsonBody(r, &v))
assert.NoError(t, Parse(r, &v))
assert.Equal(t, 1, len(v))
assert.Equal(t, "kevin", v[0].Name)
assert.Equal(t, 18, v[0].Age)
})
t.Run("form and array body", func(t *testing.T) {
var v []struct {
// we can only ignore the form tag,
// because if the value is a slice, it should be in the body,
// but it's hard to detect when we treat it as a json body.
Product string `form:"product"`
Name string `json:"name"`
Age int `json:"age"`
}
body := `[{"name":"apple", "age": 18}]`
r := httptest.NewRequest(http.MethodPost, "/a?product=tree", strings.NewReader(body))
r.Header.Set(ContentType, header.JsonContentType)
assert.NoError(t, Parse(r, &v))
assert.Equal(t, 1, len(v))
assert.Equal(t, "apple", v[0].Name)
assert.Equal(t, 18, v[0].Age)
})
}
func TestParseRequired(t *testing.T) {