Skip to content

Commit 6fa62ba

Browse files
committed
chore: Refactor doRequest function in httpclient/request.go
1 parent 86ee29f commit 6fa62ba

File tree

1 file changed

+85
-63
lines changed

1 file changed

+85
-63
lines changed

httpclient/request.go

Lines changed: 85 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -76,69 +76,6 @@ func (c *Client) DoRequest(method, endpoint string, body, out interface{}) (*htt
7676
}
7777
}
7878

79-
// doRequest contains the shared logic for making the HTTP request, including authentication,
80-
// setting headers, managing concurrency, and logging.
81-
func (c *Client) doRequest(ctx context.Context, method, endpoint string, body interface{}) (*http.Response, error) {
82-
log := c.Logger
83-
84-
clientCredentials := authenticationhandler.ClientCredentials{
85-
Username: c.clientConfig.Auth.Username,
86-
Password: c.clientConfig.Auth.Password,
87-
ClientID: c.clientConfig.Auth.ClientID,
88-
ClientSecret: c.clientConfig.Auth.ClientSecret,
89-
}
90-
91-
valid, err := c.AuthTokenHandler.CheckAndRefreshAuthToken(c.APIHandler, c.httpClient, clientCredentials, c.clientConfig.ClientOptions.Timeout.TokenRefreshBufferPeriod.Duration())
92-
if err != nil || !valid {
93-
return nil, err
94-
}
95-
96-
ctx, requestID, err := c.ConcurrencyHandler.AcquireConcurrencyPermit(ctx)
97-
if err != nil {
98-
return nil, c.Logger.Error("Failed to acquire concurrency permit", zap.Error(err))
99-
}
100-
101-
defer func() {
102-
c.ConcurrencyHandler.ReleaseConcurrencyPermit(requestID)
103-
}()
104-
105-
requestData, err := c.APIHandler.MarshalRequest(body, method, endpoint, log)
106-
if err != nil {
107-
return nil, err
108-
}
109-
110-
url := c.APIHandler.ConstructAPIResourceEndpoint(endpoint, log)
111-
req, err := http.NewRequest(method, url, bytes.NewBuffer(requestData))
112-
if err != nil {
113-
return nil, err
114-
}
115-
116-
cookiejar.ApplyCustomCookies(req, c.clientConfig.ClientOptions.Cookies.CustomCookies, log)
117-
118-
headerHandler := headers.NewHeaderHandler(req, c.Logger, c.APIHandler, c.AuthTokenHandler)
119-
headerHandler.SetRequestHeaders(endpoint)
120-
headerHandler.LogHeaders(c.clientConfig.ClientOptions.Logging.HideSensitiveData)
121-
122-
req = req.WithContext(ctx)
123-
log.LogCookies("outgoing", req, method, endpoint)
124-
125-
startTime := time.Now()
126-
resp, err := c.httpClient.Do(req)
127-
if err != nil {
128-
log.Error("Failed to send request", zap.String("method", method), zap.String("endpoint", endpoint), zap.Error(err))
129-
return nil, err
130-
}
131-
132-
duration := time.Since(startTime)
133-
c.ConcurrencyHandler.EvaluateAndAdjustConcurrency(resp, duration)
134-
log.LogCookies("incoming", req, method, endpoint)
135-
headers.CheckDeprecationHeader(resp, log)
136-
137-
log.Debug("Request sent successfully", zap.String("method", method), zap.String("endpoint", endpoint), zap.Int("status_code", resp.StatusCode))
138-
139-
return resp, nil
140-
}
141-
14279
// executeRequestWithRetries executes an HTTP request using the specified method, endpoint, request body, and output variable.
14380
// It is designed for idempotent HTTP methods (GET, PUT, DELETE), where the request can be safely retried in case of
14481
// transient errors or rate limiting. The function implements a retry mechanism that respects the client's configuration
@@ -289,3 +226,88 @@ func (c *Client) executeRequest(method, endpoint string, body, out interface{})
289226

290227
return nil, response.HandleAPIErrorResponse(res, log)
291228
}
229+
230+
// doRequest contains the shared logic for making the HTTP request, including authentication,
231+
// setting headers, managing concurrency, and logging. This function performs the following steps:
232+
// 1. Authenticates the client using the provided credentials and refreshes the auth token if necessary.
233+
// 2. Acquires a concurrency permit to control the number of concurrent requests.
234+
// 3. Increments the total request counter within the ConcurrencyHandler's metrics.
235+
// 4. Marshals the request data based on the provided body, method, and endpoint.
236+
// 5. Constructs the full URL for the API endpoint.
237+
// 6. Creates the HTTP request and applies custom cookies and headers.
238+
// 7. Executes the HTTP request and logs relevant information.
239+
// 8. Adjusts concurrency settings based on the response and logs the response details.
240+
func (c *Client) doRequest(ctx context.Context, method, endpoint string, body interface{}) (*http.Response, error) {
241+
log := c.Logger
242+
243+
// Authenticate the client using the provided credentials and refresh the auth token if necessary.
244+
clientCredentials := authenticationhandler.ClientCredentials{
245+
Username: c.clientConfig.Auth.Username,
246+
Password: c.clientConfig.Auth.Password,
247+
ClientID: c.clientConfig.Auth.ClientID,
248+
ClientSecret: c.clientConfig.Auth.ClientSecret,
249+
}
250+
251+
valid, err := c.AuthTokenHandler.CheckAndRefreshAuthToken(c.APIHandler, c.httpClient, clientCredentials, c.clientConfig.ClientOptions.Timeout.TokenRefreshBufferPeriod.Duration())
252+
if err != nil || !valid {
253+
return nil, err
254+
}
255+
256+
// Acquire a concurrency permit to control the number of concurrent requests.
257+
ctx, requestID, err := c.ConcurrencyHandler.AcquireConcurrencyPermit(ctx)
258+
if err != nil {
259+
return nil, c.Logger.Error("Failed to acquire concurrency permit", zap.Error(err))
260+
}
261+
262+
// Ensure the concurrency permit is released after the function exits.
263+
defer func() {
264+
c.ConcurrencyHandler.ReleaseConcurrencyPermit(requestID)
265+
}()
266+
267+
// Increment the total request counter within the ConcurrencyHandler's metrics.
268+
c.ConcurrencyHandler.Metrics.Lock.Lock()
269+
c.ConcurrencyHandler.Metrics.TotalRequests++
270+
c.ConcurrencyHandler.Metrics.Lock.Unlock()
271+
272+
// Marshal the request data based on the provided api handler
273+
requestData, err := c.APIHandler.MarshalRequest(body, method, endpoint, log)
274+
if err != nil {
275+
return nil, err
276+
}
277+
278+
// Construct the full URL for the API endpoint.
279+
url := c.APIHandler.ConstructAPIResourceEndpoint(endpoint, log)
280+
281+
// Create the HTTP request and apply custom cookies and headers.
282+
req, err := http.NewRequest(method, url, bytes.NewBuffer(requestData))
283+
if err != nil {
284+
return nil, err
285+
}
286+
287+
cookiejar.ApplyCustomCookies(req, c.clientConfig.ClientOptions.Cookies.CustomCookies, log)
288+
289+
headerHandler := headers.NewHeaderHandler(req, c.Logger, c.APIHandler, c.AuthTokenHandler)
290+
headerHandler.SetRequestHeaders(endpoint)
291+
headerHandler.LogHeaders(c.clientConfig.ClientOptions.Logging.HideSensitiveData)
292+
293+
req = req.WithContext(ctx)
294+
log.LogCookies("outgoing", req, method, endpoint)
295+
296+
// Execute the HTTP request and log relevant information.
297+
startTime := time.Now()
298+
resp, err := c.httpClient.Do(req)
299+
if err != nil {
300+
log.Error("Failed to send request", zap.String("method", method), zap.String("endpoint", endpoint), zap.Error(err))
301+
return nil, err
302+
}
303+
304+
// Adjust concurrency settings based on the response and log the response details.
305+
duration := time.Since(startTime)
306+
c.ConcurrencyHandler.EvaluateAndAdjustConcurrency(resp, duration)
307+
log.LogCookies("incoming", req, method, endpoint)
308+
headers.CheckDeprecationHeader(resp, log)
309+
310+
log.Debug("Request sent successfully", zap.String("method", method), zap.String("endpoint", endpoint), zap.Int("status_code", resp.StatusCode))
311+
312+
return resp, nil
313+
}

0 commit comments

Comments
 (0)