Skip to content

Commit

Permalink
feat: support json array in request body (#4444)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevwan authored Nov 5, 2024
1 parent 1940f7b commit 53a7475
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
20 changes: 12 additions & 8 deletions rest/httpx/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package httpx
import (
"io"
"net/http"
"reflect"
"strings"
"sync/atomic"

Expand Down Expand Up @@ -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 {
Expand Down
22 changes: 21 additions & 1 deletion rest/httpx/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 53a7475

Please sign in to comment.