Skip to content

Commit

Permalink
Cleaned up doRequest and broke it up into helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
ezilber-akamai committed Jul 31, 2024
1 parent 3fa0585 commit a0a4840
Showing 1 changed file with 98 additions and 57 deletions.
155 changes: 98 additions & 57 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,41 +133,82 @@ type RequestParams struct {
Response any
}

// Generic helper to execute HTTP requests using the
// Generic helper to execute HTTP requests using the net/http package
//
//nolint:gocognit,unused,funlen
// nolint:unused
func (c *httpClient) doRequest(ctx context.Context, method, url string, params RequestParams, mutators ...func(req *http.Request) error) error {
// Create a new HTTP request
req, bodyBuffer, err := c.createRequest(ctx, method, url, params)
if err != nil {
return err
}

if err := c.applyMutators(req, mutators); err != nil {
return err
}

if c.debug && c.logger != nil {
c.logRequest(req, method, url, bodyBuffer)
}

resp, err := c.sendRequest(req)
if err != nil {
return err
}
defer resp.Body.Close()

if err := c.checkHTTPError(resp); err != nil {
return err
}

if c.debug && c.logger != nil {
resp, err = c.logResponse(resp)
if err != nil {
return err
}
}

if params.Response != nil {
if err := c.decodeResponseBody(resp, params.Response); err != nil {
return err
}
}

return nil
}

func (c *httpClient) createRequest(ctx context.Context, method, url string, params RequestParams) (*http.Request, *bytes.Buffer, error) {

Check failure on line 179 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).createRequest` is unused (unused)
var bodyReader io.Reader
var bodyBuffer *bytes.Buffer

if params.Body != nil {
buf := new(bytes.Buffer)
if err := json.NewEncoder(buf).Encode(params.Body); err != nil {
bodyBuffer = new(bytes.Buffer)
if err := json.NewEncoder(bodyBuffer).Encode(params.Body); err != nil {
if c.debug && c.logger != nil {
c.logger.Errorf("failed to encode body: %v", err)
}
return fmt.Errorf("failed to encode body: %w", err)
return nil, nil, fmt.Errorf("failed to encode body: %w", err)
}
bodyReader = buf
bodyReader = bodyBuffer
}

req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
if err != nil {
if c.debug && c.logger != nil {
c.logger.Errorf("failed to create request: %v", err)
}
return fmt.Errorf("failed to create request: %w", err)
return nil, nil, fmt.Errorf("failed to create request: %w", err)
}

// Set default headers
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
if c.userAgent != "" {
req.Header.Set("User-Agent", c.userAgent)
}

// Apply mutators
return req, bodyBuffer, nil
}

func (c *httpClient) applyMutators(req *http.Request, mutators []func(req *http.Request) error) error {

Check failure on line 211 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).applyMutators` is unused (unused)
for _, mutate := range mutators {
if err := mutate(req); err != nil {
if c.debug && c.logger != nil {
Expand All @@ -176,76 +217,76 @@ func (c *httpClient) doRequest(ctx context.Context, method, url string, params R
return fmt.Errorf("failed to mutate request: %w", err)
}
}
return nil
}

// Log the request if in debug mode
if c.debug && c.logger != nil {
var reqBody string
if bodyBuffer != nil {
reqBody = bodyBuffer.String()
}
func (c *httpClient) logRequest(req *http.Request, method, url string, bodyBuffer *bytes.Buffer) {

Check failure on line 223 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).logRequest` is unused (unused)
var reqBody string
if bodyBuffer != nil {
reqBody = bodyBuffer.String()
}

var logBuf bytes.Buffer
err = reqLogTemplate.Execute(&logBuf, map[string]interface{}{
"Method": method,
"URL": url,
"Headers": req.Header,
"Body": reqBody,
})
if err == nil {
c.logger.Debugf(logBuf.String())
}
var logBuf bytes.Buffer
err := reqLogTemplate.Execute(&logBuf, map[string]interface{}{
"Method": method,
"URL": url,
"Headers": req.Header,
"Body": reqBody,
})
if err == nil {
c.logger.Debugf(logBuf.String())
}
}

// Send the request
func (c *httpClient) sendRequest(req *http.Request) (*http.Response, error) {

Check failure on line 241 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).sendRequest` is unused (unused)
resp, err := c.httpClient.Do(req)
if err != nil {
if c.debug && c.logger != nil {
c.logger.Errorf("failed to send request: %v", err)
}
return fmt.Errorf("failed to send request: %w", err)
return nil, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
return resp, nil
}

// Check for HTTP errors
resp, err = coupleAPIErrorsHTTP(resp, err)
func (c *httpClient) checkHTTPError(resp *http.Response) error {

Check failure on line 252 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).checkHTTPError` is unused (unused)
resp, err := coupleAPIErrorsHTTP(resp, nil)

Check failure on line 253 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

ineffectual assignment to resp (ineffassign)
if err != nil {
if c.debug && c.logger != nil {
c.logger.Errorf("received HTTP error: %v", err)
}
return err
}
return nil
}

// Log the response if in debug mode
if c.debug && c.logger != nil {
var respBody bytes.Buffer
if _, err := io.Copy(&respBody, resp.Body); err != nil {
c.logger.Errorf("failed to read response body: %v", err)
}

var logBuf bytes.Buffer
err = respLogTemplate.Execute(&logBuf, map[string]interface{}{
"Status": resp.Status,
"Headers": resp.Header,
"Body": respBody.String(),
})
if err == nil {
c.logger.Debugf(logBuf.String())
}
func (c *httpClient) logResponse(resp *http.Response) (*http.Response, error) {

Check failure on line 263 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).logResponse` is unused (unused)
var respBody bytes.Buffer
if _, err := io.Copy(&respBody, resp.Body); err != nil {
c.logger.Errorf("failed to read response body: %v", err)
}

// Reset the response body reader for actual decoding
resp.Body = io.NopCloser(bytes.NewReader(respBody.Bytes()))
var logBuf bytes.Buffer
err := respLogTemplate.Execute(&logBuf, map[string]interface{}{
"Status": resp.Status,
"Headers": resp.Header,
"Body": respBody.String(),
})
if err == nil {
c.logger.Debugf(logBuf.String())
}

// Decode the response body
if params.Response != nil {
if err := json.NewDecoder(resp.Body).Decode(params.Response); err != nil {
if c.debug && c.logger != nil {
c.logger.Errorf("failed to decode response: %v", err)
}
return fmt.Errorf("failed to decode response: %w", err)
resp.Body = io.NopCloser(bytes.NewReader(respBody.Bytes()))
return resp, nil
}

func (c *httpClient) decodeResponseBody(resp *http.Response, response interface{}) error {

Check failure on line 283 in client.go

View workflow job for this annotation

GitHub Actions / lint-tidy

func `(*httpClient).decodeResponseBody` is unused (unused)
if err := json.NewDecoder(resp.Body).Decode(response); err != nil {
if c.debug && c.logger != nil {
c.logger.Errorf("failed to decode response: %v", err)
}
return fmt.Errorf("failed to decode response: %w", err)
}

return nil
}

Expand Down

0 comments on commit a0a4840

Please sign in to comment.