Created
October 23, 2023 14:10
-
-
Save lxdlam/4c70cd8c654c04e99b50b1b043b43437 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package http | |
import ( | |
"bytes" | |
"context" | |
"encoding/json" | |
"io" | |
"net/http" | |
) | |
type ClientConfig struct { | |
Endpoint string | |
Headers map[string]string | |
} | |
type Client struct { | |
client *http.Client | |
config *ClientConfig | |
} | |
func NewClient(config *ClientConfig) *Client { | |
return &Client{ | |
client: &http.Client{}, | |
config: config, | |
} | |
} | |
func (h *Client) URL(path string) string { | |
return h.config.Endpoint + path | |
} | |
func (h *Client) Do(req *http.Request) (*http.Response, error) { | |
for k, v := range h.config.Headers { | |
req.Header.Add(k, v) | |
} | |
return h.client.Do(req) | |
} | |
type httpOpt func(*http.Request) | |
func WithQuery(key, value string) httpOpt { | |
return func(req *http.Request) { | |
q := req.URL.Query() | |
q.Add(key, value) | |
req.URL.RawQuery = q.Encode() | |
} | |
} | |
type ClientFuncion[I, O any] func(context.Context, *I, ...httpOpt) (*O, error) | |
type ClientFunctionNoInput[O any] func(context.Context, ...httpOpt) (*O, error) | |
func Method[I, O any](client *Client, method, path string) ClientFuncion[I, O] { | |
return func(ctx context.Context, i *I, ho ...httpOpt) (*O, error) { | |
reqBody, err := json.Marshal(i) | |
if err != nil { | |
return nil, err | |
} | |
req, err := http.NewRequest(method, path, bytes.NewReader(reqBody)) | |
if err != nil { | |
return nil, err | |
} | |
for _, o := range ho { | |
o(req) | |
} | |
resp, err := client.Do(req) | |
if err != nil { | |
return nil, err | |
} | |
defer resp.Body.Close() | |
respBody, err := io.ReadAll(resp.Body) | |
if err != nil { | |
return nil, err | |
} | |
ret := new(O) | |
if err := json.Unmarshal(respBody, &ret); err != nil { | |
return nil, err | |
} | |
return ret, nil | |
} | |
} | |
func MethodEmitInput[O any](client *Client, method, path string) ClientFunctionNoInput[O] { | |
return func(ctx context.Context, ho ...httpOpt) (*O, error) { | |
req, err := http.NewRequest(method, path, nil) | |
if err != nil { | |
return nil, err | |
} | |
for _, o := range ho { | |
o(req) | |
} | |
resp, err := client.Do(req) | |
if err != nil { | |
return nil, err | |
} | |
defer resp.Body.Close() | |
respBody, err := io.ReadAll(resp.Body) | |
if err != nil { | |
return nil, err | |
} | |
ret := new(O) | |
if err := json.Unmarshal(respBody, &ret); err != nil { | |
return nil, err | |
} | |
return ret, nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment