Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"net/http"
"net/url"
"time"

"github.com/tinh-tinh/tinhtinh/v2/core"
)

type Config struct {
Expand All @@ -27,6 +29,10 @@ type Config struct {
ResponseType string
// Cancel token
CancelToken context.Context
// Encoder
Encoder core.Encode
// Decoder
Decoder core.Decode
}

// GetConfig returns a new *http.Request with the given method, uri and input.
Expand All @@ -40,7 +46,7 @@ func (f *Fetch) GetConfig(method string, uri string, input io.Reader) (*http.Req
formatUrl = f.Config.BaseUrl
}

formatUrl += IfSlashPrefixString(uri)
formatUrl += core.IfSlashPrefixString(uri)
if len(f.Config.Params) > 0 {
formatUrl += "?" + ParseQuery(f.Config.Params)
}
Expand Down
17 changes: 13 additions & 4 deletions fetch.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fetch

import (
"encoding/json"
"io"
"net/http"
)
Expand All @@ -15,6 +16,12 @@ type Fetch struct {
// The configuration includes details like BaseUrl, Headers, Params, and more,
// which are used to customize HTTP requests made by the Fetch instance.
func Create(config *Config) *Fetch {
if config.Encoder == nil {
config.Encoder = json.Marshal
}
if config.Decoder == nil {
config.Decoder = json.Unmarshal
}
return &Fetch{
Config: config,
}
Expand Down Expand Up @@ -51,7 +58,7 @@ func (f *Fetch) Post(url string, data interface{}, params ...interface{}) *Respo
url += "?" + ParseQuery(params)
}

return f.do("POST", url, ParseData(data))
return f.do("POST", url, ParseData(data, f.Config.Encoder))
}

// Patch makes a PATCH request to the specified URL and returns a Response
Expand All @@ -70,7 +77,7 @@ func (f *Fetch) Patch(url string, data interface{}, params ...interface{}) *Resp
url += "?" + ParseQuery(params)
}

return f.do("PATCH", url, ParseData(data))
return f.do("PATCH", url, ParseData(data, f.Config.Encoder))
}

// Put makes a PUT request to the specified URL and returns a Response
Expand All @@ -89,7 +96,7 @@ func (f *Fetch) Put(url string, data interface{}, params ...interface{}) *Respon
url += "?" + ParseQuery(params)
}

return f.do("PUT", url, ParseData(data))
return f.do("PUT", url, ParseData(data, f.Config.Encoder))
}

// Delete makes a DELETE request to the specified URL and returns a Response
Expand Down Expand Up @@ -133,7 +140,9 @@ func (f *Fetch) do(method string, uri string, input io.Reader) *Response {
client.Timeout = f.Config.Timeout
}

response := &Response{}
response := &Response{
decoder: f.Config.Decoder,
}
resp, err := client.Do(req)
if err != nil {
response.Error = err
Expand Down
7 changes: 5 additions & 2 deletions response.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package fetch

import "encoding/json"
import (
"github.com/tinh-tinh/tinhtinh/v2/core"
)

type Response struct {
Data []byte
Status int
StatusText string
Error error
decoder core.Decode
}

// Format deserializes the response data into the given model. If the model is nil, the method does nothing.
// If the deserialization fails, the error is stored in the Response instance.
func (r *Response) Format(model interface{}) *Response {
if model != nil {
err := json.Unmarshal(r.Data, model)
err := r.decoder(r.Data, model)
if err != nil {
r.Error = err
}
Expand Down
1 change: 1 addition & 0 deletions response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func Test_Schema(t *testing.T) {
res := instance.Get("comments", &QueryComment{
PostID: 1,
}).Format(&comments)

require.Nil(t, res.Error)
require.Equal(t, 200, res.Status)
if len(comments) > 0 {
Expand Down
28 changes: 4 additions & 24 deletions utils.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package fetch

import (
"encoding/json"
"fmt"
"io"
"log"
"reflect"
"strconv"
"strings"

"github.com/tinh-tinh/tinhtinh/v2/core"
)

// ParseQuery takes an interface{} argument and returns a string representing
Expand Down Expand Up @@ -99,34 +100,13 @@ func ParseQuery(queryVal interface{}) string {
// containing the JSON data. If the input data is nil, the function returns nil.
// If the serialization fails, the function panics. The returned io.Reader can
// be used to read the JSON data as a stream.
func ParseData(data interface{}) io.Reader {
func ParseData(data interface{}, encoder core.Encode) io.Reader {
if data == nil {
return nil
}
buffer, err := json.Marshal(data)
buffer, err := encoder(data)
if err != nil {
panic(err)
}
return strings.NewReader(string(buffer))
}

// IfSlashPrefixString trims a trailing slash from the string if present,
// and ensures that the resulting string has a leading slash. If the input
// string is empty, it returns the empty string. The function formats the
// string using the ToFormat function before returning it.
func IfSlashPrefixString(s string) string {
if s == "" {
return s
}
s = strings.TrimSuffix(s, "/")
if strings.HasPrefix(s, "/") {
return ToFormat(s)
}
return "/" + ToFormat(s)
}

// ToFormat takes a string and returns a formatted string. The string is
// converted to lowercase and spaces are removed.
func ToFormat(s string) string {
return strings.ReplaceAll(s, " ", "")
}
5 changes: 3 additions & 2 deletions utils_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fetch_test

import (
"encoding/json"
"strings"
"testing"

Expand Down Expand Up @@ -78,10 +79,10 @@ func Test_ParseData(t *testing.T) {
Age: 13,
}

str := fetch.ParseData(data)
str := fetch.ParseData(data, json.Marshal)
reader := strings.NewReader("{\"name\":\"Abc\",\"age\":13}")
require.Equal(t, reader, str)

null := fetch.ParseData(nil)
null := fetch.ParseData(nil, json.Marshal)
require.Nil(t, null)
}