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"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/encoding/json"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
@ -59,6 +61,18 @@ type Client struct {
|
|||
// NoDefaultUserAgentHeader when set to true, causes the default
|
||||
// User-Agent header to be excluded from the Request.
|
||||
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.
|
||||
|
@ -116,6 +130,8 @@ func (c *Client) createAgent(method, url string) *Agent {
|
|||
|
||||
a.Name = c.UserAgent
|
||||
a.NoDefaultUserAgentHeader = c.NoDefaultUserAgentHeader
|
||||
a.jsonDecoder = c.JSONDecoder
|
||||
a.jsonEncoder = c.JSONEncoder
|
||||
|
||||
if err := a.Parse(); err != nil {
|
||||
a.errs = append(a.errs, err)
|
||||
|
@ -135,6 +151,8 @@ type Agent struct {
|
|||
formFiles []*FormFile
|
||||
debugWriter io.Writer
|
||||
mw multipartWriter
|
||||
jsonEncoder utils.JSONMarshal
|
||||
jsonDecoder utils.JSONUnmarshal
|
||||
maxRedirectsCount int
|
||||
boundary string
|
||||
Name string
|
||||
|
@ -450,9 +468,13 @@ func (a *Agent) Request(req *Request) *Agent {
|
|||
|
||||
// JSON sends a JSON request.
|
||||
func (a *Agent) JSON(v interface{}) *Agent {
|
||||
if a.jsonEncoder == nil {
|
||||
a.jsonEncoder = json.Marshal
|
||||
}
|
||||
|
||||
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)
|
||||
} else {
|
||||
a.req.SetBody(body)
|
||||
|
@ -658,6 +680,20 @@ func (a *Agent) MaxRedirectsCount(count int) *Agent {
|
|||
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 **************************/
|
||||
|
||||
// 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.
|
||||
// And bytes body will be unmarshalled to given v.
|
||||
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...)
|
||||
|
||||
if err := json.Unmarshal(body, v); err != nil {
|
||||
if err := a.jsonDecoder(body, v); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2/internal/encoding/json"
|
||||
|
||||
"github.com/gofiber/fiber/v2/utils"
|
||||
"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) {
|
||||
a := Get("http://example.com").
|
||||
JSONEncoder(json.Marshal).
|
||||
JSON(complex(1, 1))
|
||||
|
||||
_, body, errs := a.String()
|
||||
|
@ -947,7 +950,8 @@ func Test_Client_Agent_Struct(t *testing.T) {
|
|||
|
||||
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, `{"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