mobilenig.*Client.do   A
last analyzed

Complexity

Conditions 5

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nop 1
dl 0
loc 19
rs 9.3333
c 0
b 0
f 0
1
package mobilenig
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"io"
7
	"io/ioutil"
8
	"net/http"
9
)
10
11
const (
12
	apiBaseURL = "https://mobilenig.com/API"
13
)
14
15
type service struct {
16
	client *Client
17
}
18
19
// Client is the MobileNig API client.
20
// Do not instantiate this client with Client{}. Use the New method instead.
21
type Client struct {
22
	httpClient  *http.Client
23
	common      service
24
	environment Environment
25
	username    string
26
	apiKey      string
27
	baseURL     string
28
	Bills       *BillsService
29
}
30
31
// New creates and returns a new mobilenig.Client from a slice of mobilenig.ClientOption.
32
func New(options ...ClientOption) *Client {
33
	config := defaultClientConfig()
34
35
	for _, option := range options {
36
		option.apply(config)
37
	}
38
39
	client := &Client{
40
		httpClient:  config.httpClient,
41
		environment: config.environment,
42
		username:    config.username,
43
		baseURL:     config.baseURL,
44
		apiKey:      config.apiKey,
45
	}
46
47
	client.common.client = client
48
	client.Bills = (*BillsService)(&client.common)
49
	return client
50
}
51
52
// newRequest creates an API request. A relative URL can be provided in uri,
53
// in which case it is resolved relative to the apiBaseURL of the Client.
54
// URI's should always be specified without a preceding slash.
55
func (client *Client) newRequest(ctx context.Context, uri string, params map[string]string) (*http.Request, error) {
56
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, client.baseURL+uri, nil)
57
	if err != nil {
58
		return nil, err
59
	}
60
61
	q := req.URL.Query()
62
63
	q.Add("username", client.username)
64
	q.Add("api_key", client.apiKey)
65
66
	for key, value := range params {
67
		q.Add(key, value)
68
	}
69
70
	req.URL.RawQuery = q.Encode()
71
72
	return req, nil
73
}
74
75
// do carries out an HTTP request and returns a Response
76
func (client *Client) do(req *http.Request) (*Response, error) {
77
	httpResponse, err := client.httpClient.Do(req)
78
	if err != nil {
79
		return nil, err
80
	}
81
82
	defer func() { _ = httpResponse.Body.Close() }()
83
84
	resp, err := client.newResponse(httpResponse)
85
	if err != nil {
86
		return resp, err
87
	}
88
89
	_, err = io.Copy(ioutil.Discard, httpResponse.Body)
90
	if err != nil {
91
		return resp, err
92
	}
93
94
	return resp, nil
95
}
96
97
// newResponse converts an *http.Response to *Response
98
func (client *Client) newResponse(httpResponse *http.Response) (*Response, error) {
99
	resp := new(Response)
100
	resp.HTTPResponse = httpResponse
101
102
	buf, err := ioutil.ReadAll(resp.HTTPResponse.Body)
103
	if err != nil {
104
		return nil, err
105
	}
106
	resp.Body = &buf
107
108
	errResponse := new(ErrorResponse)
109
	err = json.Unmarshal(*resp.Body, errResponse)
110
	if err == nil {
111
		resp.Error = errResponse
112
	}
113
114
	return resp, resp.Err()
115
}
116