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) }