ozon-api-client
/
client.go
132 строки · 2.6 Кб
1package core
2
3import (
4"bytes"
5"context"
6"encoding/json"
7"io/ioutil"
8"net/http"
9"net/http/httptest"
10"net/url"
11"reflect"
12)
13
14type HttpClient interface {
15Do(req *http.Request) (*http.Response, error)
16}
17
18type Client struct {
19baseUrl string
20Options map[string]string
21
22client HttpClient
23}
24
25func NewClient(client HttpClient, baseUrl string, opts map[string]string) *Client {
26return &Client{
27Options: opts,
28client: client,
29baseUrl: baseUrl,
30}
31}
32
33func NewMockClient(handler http.HandlerFunc) *Client {
34return &Client{
35client: NewMockHttpClient(handler),
36}
37}
38
39func (c Client) newRequest(ctx context.Context, method string, uri string, body interface{}) (*http.Request, error) {
40var err error
41var bodyJson []byte
42
43// Set default values for empty fields if `default` tag is present
44// And body is not nil
45if body != nil {
46if err := getDefaultValues(reflect.ValueOf(body)); err != nil {
47return nil, err
48}
49
50bodyJson, err = json.Marshal(body)
51if err != nil {
52return nil, err
53}
54}
55
56uri, err = url.JoinPath(c.baseUrl, uri)
57if err != nil {
58return nil, err
59}
60req, err := http.NewRequestWithContext(ctx, method, uri, bytes.NewBuffer(bodyJson))
61if err != nil {
62return nil, err
63}
64
65for k, v := range c.Options {
66req.Header.Add(k, v)
67}
68
69return req, nil
70}
71
72func (c Client) Request(ctx context.Context, method string, path string, req, resp interface{}, options map[string]string) (*Response, error) {
73httpReq, err := c.newRequest(ctx, method, path, req)
74if err != nil {
75return nil, err
76}
77
78httpResp, err := c.client.Do(httpReq)
79if err != nil {
80return nil, err
81}
82defer httpResp.Body.Close()
83
84body, err := ioutil.ReadAll(httpResp.Body)
85if err != nil {
86return nil, err
87}
88
89response := &Response{}
90response.Data = resp
91response.StatusCode = httpResp.StatusCode
92if httpResp.StatusCode == http.StatusOK {
93err = json.Unmarshal(body, &response.Data)
94} else {
95err = json.Unmarshal(body, &response)
96}
97if err != nil {
98return nil, err
99}
100
101return response, nil
102}
103
104type MockHttpClient struct {
105handler http.HandlerFunc
106}
107
108func NewMockHttpClient(handler http.HandlerFunc) *MockHttpClient {
109return &MockHttpClient{
110handler: handler,
111}
112}
113
114func (c MockHttpClient) Do(req *http.Request) (*http.Response, error) {
115rr := httptest.NewRecorder()
116c.handler.ServeHTTP(rr, req)
117
118return rr.Result(), nil
119}
120
121func NewMockHttpHandler(statusCode int, json string, headers map[string]string) http.HandlerFunc {
122return func(w http.ResponseWriter, r *http.Request) {
123if len(headers) > 0 {
124for key, value := range headers {
125w.Header().Add(key, value)
126}
127}
128
129w.WriteHeader(statusCode)
130w.Write([]byte(json))
131}
132}
133