mirror of https://github.com/gofiber/fiber.git
👷 Add JSONEncoder and JSONDecoder
parent
c477128e5b
commit
c34ca83c06
44
client.go
44
client.go
|
@ -16,6 +16,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2/utils"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2/internal/encoding/json"
|
"github.com/gofiber/fiber/v2/internal/encoding/json"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
@ -59,6 +61,18 @@ type Client struct {
|
||||||
// NoDefaultUserAgentHeader when set to true, causes the default
|
// NoDefaultUserAgentHeader when set to true, causes the default
|
||||||
// User-Agent header to be excluded from the Request.
|
// User-Agent header to be excluded from the Request.
|
||||||
NoDefaultUserAgentHeader bool
|
NoDefaultUserAgentHeader bool
|
||||||
|
|
||||||
|
// When set by an external client of Fiber it will use the provided implementation of a
|
||||||
|
// JSONMarshal
|
||||||
|
//
|
||||||
|
// Allowing for flexibility in using another json library for encoding
|
||||||
|
JSONEncoder utils.JSONMarshal
|
||||||
|
|
||||||
|
// When set by an external client of Fiber it will use the provided implementation of a
|
||||||
|
// JSONUnmarshal
|
||||||
|
//
|
||||||
|
// Allowing for flexibility in using another json library for decoding
|
||||||
|
JSONDecoder utils.JSONUnmarshal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a agent with http method GET.
|
// Get returns a agent with http method GET.
|
||||||
|
@ -116,6 +130,8 @@ func (c *Client) createAgent(method, url string) *Agent {
|
||||||
|
|
||||||
a.Name = c.UserAgent
|
a.Name = c.UserAgent
|
||||||
a.NoDefaultUserAgentHeader = c.NoDefaultUserAgentHeader
|
a.NoDefaultUserAgentHeader = c.NoDefaultUserAgentHeader
|
||||||
|
a.jsonDecoder = c.JSONDecoder
|
||||||
|
a.jsonEncoder = c.JSONEncoder
|
||||||
|
|
||||||
if err := a.Parse(); err != nil {
|
if err := a.Parse(); err != nil {
|
||||||
a.errs = append(a.errs, err)
|
a.errs = append(a.errs, err)
|
||||||
|
@ -135,6 +151,8 @@ type Agent struct {
|
||||||
formFiles []*FormFile
|
formFiles []*FormFile
|
||||||
debugWriter io.Writer
|
debugWriter io.Writer
|
||||||
mw multipartWriter
|
mw multipartWriter
|
||||||
|
jsonEncoder utils.JSONMarshal
|
||||||
|
jsonDecoder utils.JSONUnmarshal
|
||||||
maxRedirectsCount int
|
maxRedirectsCount int
|
||||||
boundary string
|
boundary string
|
||||||
Name string
|
Name string
|
||||||
|
@ -450,9 +468,13 @@ func (a *Agent) Request(req *Request) *Agent {
|
||||||
|
|
||||||
// JSON sends a JSON request.
|
// JSON sends a JSON request.
|
||||||
func (a *Agent) JSON(v interface{}) *Agent {
|
func (a *Agent) JSON(v interface{}) *Agent {
|
||||||
|
if a.jsonEncoder == nil {
|
||||||
|
a.jsonEncoder = json.Marshal
|
||||||
|
}
|
||||||
|
|
||||||
a.req.Header.SetContentType(MIMEApplicationJSON)
|
a.req.Header.SetContentType(MIMEApplicationJSON)
|
||||||
|
|
||||||
if body, err := json.Marshal(v); err != nil {
|
if body, err := a.jsonEncoder(v); err != nil {
|
||||||
a.errs = append(a.errs, err)
|
a.errs = append(a.errs, err)
|
||||||
} else {
|
} else {
|
||||||
a.req.SetBody(body)
|
a.req.SetBody(body)
|
||||||
|
@ -658,6 +680,20 @@ func (a *Agent) MaxRedirectsCount(count int) *Agent {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSONEncoder sets custom json encoder.
|
||||||
|
func (a *Agent) JSONEncoder(jsonEncoder utils.JSONMarshal) *Agent {
|
||||||
|
a.jsonEncoder = jsonEncoder
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSONDecoder sets custom json decoder.
|
||||||
|
func (a *Agent) JSONDecoder(jsonDecoder utils.JSONUnmarshal) *Agent {
|
||||||
|
a.jsonDecoder = jsonDecoder
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
/************************** End Agent Setting **************************/
|
/************************** End Agent Setting **************************/
|
||||||
|
|
||||||
// Bytes returns the status code, bytes body and errors of url.
|
// Bytes returns the status code, bytes body and errors of url.
|
||||||
|
@ -738,9 +774,13 @@ func (a *Agent) String(resp ...*Response) (int, string, []error) {
|
||||||
// Struct returns the status code, bytes body and errors of url.
|
// Struct returns the status code, bytes body and errors of url.
|
||||||
// And bytes body will be unmarshalled to given v.
|
// And bytes body will be unmarshalled to given v.
|
||||||
func (a *Agent) Struct(v interface{}, resp ...*Response) (code int, body []byte, errs []error) {
|
func (a *Agent) Struct(v interface{}, resp ...*Response) (code int, body []byte, errs []error) {
|
||||||
|
if a.jsonDecoder == nil {
|
||||||
|
a.jsonDecoder = json.Unmarshal
|
||||||
|
}
|
||||||
|
|
||||||
code, body, errs = a.Bytes(resp...)
|
code, body, errs = a.Bytes(resp...)
|
||||||
|
|
||||||
if err := json.Unmarshal(body, v); err != nil {
|
if err := a.jsonDecoder(body, v); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2/internal/encoding/json"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2/utils"
|
"github.com/gofiber/fiber/v2/utils"
|
||||||
"github.com/valyala/fasthttp/fasthttputil"
|
"github.com/valyala/fasthttp/fasthttputil"
|
||||||
)
|
)
|
||||||
|
@ -532,6 +534,7 @@ func Test_Client_Agent_Json(t *testing.T) {
|
||||||
|
|
||||||
func Test_Client_Agent_Json_Error(t *testing.T) {
|
func Test_Client_Agent_Json_Error(t *testing.T) {
|
||||||
a := Get("http://example.com").
|
a := Get("http://example.com").
|
||||||
|
JSONEncoder(json.Marshal).
|
||||||
JSON(complex(1, 1))
|
JSON(complex(1, 1))
|
||||||
|
|
||||||
_, body, errs := a.String()
|
_, body, errs := a.String()
|
||||||
|
@ -947,7 +950,8 @@ func Test_Client_Agent_Struct(t *testing.T) {
|
||||||
|
|
||||||
var d data
|
var d data
|
||||||
|
|
||||||
code, body, errs := a.Struct(&d)
|
code, body, errs := a.JSONDecoder(json.Unmarshal).
|
||||||
|
Struct(&d)
|
||||||
|
|
||||||
utils.AssertEqual(t, StatusOK, code)
|
utils.AssertEqual(t, StatusOK, code)
|
||||||
utils.AssertEqual(t, `{"success"`, string(body))
|
utils.AssertEqual(t, `{"success"`, string(body))
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
// JSONMarshal returns the JSON encoding of v.
|
||||||
|
type JSONMarshal func(v interface{}) ([]byte, error)
|
||||||
|
|
||||||
|
// JSONUnmarshal parses the JSON-encoded data and stores the result
|
||||||
|
// in the value pointed to by v. If v is nil or not a pointer,
|
||||||
|
// Unmarshal returns an InvalidUnmarshalError.
|
||||||
|
type JSONUnmarshal func(data []byte, v interface{}) error
|
|
@ -1,5 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
// JSONMarshal is the standard definition of representing a Go structure in
|
|
||||||
// json format
|
|
||||||
type JSONMarshal func(interface{}) ([]byte, error)
|
|
|
@ -1,26 +0,0 @@
|
||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestDefaultJSONEncoder(t *testing.T) {
|
|
||||||
type SampleStructure struct {
|
|
||||||
ImportantString string `json:"important_string"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
sampleStructure = &SampleStructure{
|
|
||||||
ImportantString: "Hello World",
|
|
||||||
}
|
|
||||||
importantString = `{"important_string":"Hello World"}`
|
|
||||||
|
|
||||||
jsonEncoder JSONMarshal = json.Marshal
|
|
||||||
)
|
|
||||||
|
|
||||||
raw, err := jsonEncoder(sampleStructure)
|
|
||||||
AssertEqual(t, err, nil)
|
|
||||||
|
|
||||||
AssertEqual(t, string(raw), importantString)
|
|
||||||
}
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sampleStructure struct {
|
||||||
|
ImportantString string `json:"important_string"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_DefaultJSONEncoder(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var (
|
||||||
|
ss = &sampleStructure{
|
||||||
|
ImportantString: "Hello World",
|
||||||
|
}
|
||||||
|
importantString = `{"important_string":"Hello World"}`
|
||||||
|
jsonEncoder JSONMarshal = json.Marshal
|
||||||
|
)
|
||||||
|
|
||||||
|
raw, err := jsonEncoder(ss)
|
||||||
|
AssertEqual(t, err, nil)
|
||||||
|
|
||||||
|
AssertEqual(t, string(raw), importantString)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_DefaultJSONDecoder(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var (
|
||||||
|
ss sampleStructure
|
||||||
|
importantString = []byte(`{"important_string":"Hello World"}`)
|
||||||
|
jsonDecoder JSONUnmarshal = json.Unmarshal
|
||||||
|
)
|
||||||
|
|
||||||
|
err := jsonDecoder(importantString, &ss)
|
||||||
|
AssertEqual(t, err, nil)
|
||||||
|
AssertEqual(t, "Hello World", ss.ImportantString)
|
||||||
|
}
|
Loading…
Reference in New Issue