96 lines
1.7 KiB
Go

package request
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/url"
)
const (
defaultHost = "api.weixin.qq.com"
)
type Option func(*Request)
type Request struct {
Host string
Path string
Params url.Values
Fragment string
}
func WithHost(host string) Option {
return func(r *Request) {
r.Host = host
}
}
func WithFragment(fragment string) Option {
return func(r *Request) {
r.Fragment = fragment
}
}
func New(path string, params url.Values, opts ...Option) *Request {
r := Request{
Host: defaultHost,
Path: path,
Params: params,
}
for _, opt := range opts {
opt(&r)
}
return &r
}
func (r Request) Endpoint() string {
u := url.URL{
Scheme: "https",
Host: r.Host,
Path: r.Path,
RawQuery: r.Params.Encode(),
Fragment: r.Fragment,
}
return u.String()
}
func (r Request) Get(ctx context.Context, result interface{}) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.Endpoint(), nil)
if err != nil {
return nil
}
return r.SendRequest(req, result)
}
func (r Request) Post(ctx context.Context, data interface{}, result interface{}) error {
dataBytes, err := json.Marshal(data)
if err != nil {
return err
}
body := bytes.NewReader(dataBytes)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.Endpoint(), body)
if err != nil {
return nil
}
return r.SendRequest(req, result)
}
func (r Request) SendRequest(req *http.Request, result interface{}) error {
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return json.Unmarshal(body, &result)
}