70 lines
2.2 KiB
Go
70 lines
2.2 KiB
Go
package mutil
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
|
|
api "github.com/tech/sendico/pkg/api/http"
|
|
"github.com/tech/sendico/pkg/mlogger"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func SendAPIRequest(ctx context.Context, logger mlogger.Logger, httpMethod api.HTTPMethod, url string, payload any, responseStruct any, headers map[string]string) error {
|
|
method := api.HTTPMethod2String(httpMethod)
|
|
|
|
var reqBody io.Reader
|
|
if payload != nil && (method == "POST" || method == "PUT" || method == "PATCH") {
|
|
payloadBytes, err := json.Marshal(payload)
|
|
if err != nil {
|
|
logger.Warn("Failed to encode payload", zap.Error(err), zap.String("url", url), zap.Any("payload", payload))
|
|
return err
|
|
}
|
|
reqBody = bytes.NewBuffer(payloadBytes)
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(ctx, method, url, reqBody)
|
|
if err != nil {
|
|
logger.Warn("Failed to prepare request", zap.Error(err), zap.String("url", url),
|
|
zap.String("method", method), zap.Any("payload", payload))
|
|
return err
|
|
}
|
|
|
|
if reqBody != nil {
|
|
// Set the content type header for srequest with a body
|
|
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
|
|
}
|
|
|
|
// Add custom headers
|
|
for key, value := range headers {
|
|
req.Header.Set(key, value)
|
|
}
|
|
|
|
// Create an HTTP client with a timeout
|
|
client := http.Client{}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
logger.Warn("Failed to execute request", zap.Error(err), zap.String("method", method), zap.String("url", url), zap.Any("payload", payload))
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// Read the sresponse body
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
logger.Warn("Failed to read sresponse", zap.Error(err), zap.String("method", method), zap.String("url", url), zap.Any("payload", payload))
|
|
return err
|
|
}
|
|
logger.Debug("Remote party sresponse", zap.String("url", url), zap.String("method", method), zap.Any("payload", payload), zap.Binary("sresponse", body))
|
|
|
|
// Unmarshal sresponse JSON to struct
|
|
if err = json.Unmarshal(body, responseStruct); err != nil {
|
|
logger.Warn("Failed to read sresponse", zap.Error(err), zap.String("method", method), zap.String("url", url), zap.Any("payload", payload), zap.Binary("sresponse", body))
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|