package httputil import ( "bytes" "encoding/json" "fmt" "io" "net/http" "satusehat-rssa/internal/constant" "time" ) // RequestOption for request configuration type RequestOption struct { Method string URL string Body interface{} Headers map[string]string BearerToken string Timeout time.Duration } // DoRequest sends an HTTP request and returns the result as map[string]interface{} func DoRequest(opt RequestOption) (map[string]interface{}, error) { if opt.Method == "" { opt.Method = http.MethodGet } var bodyReader io.Reader if opt.Body != nil { jsonData, err := json.Marshal(opt.Body) if err != nil { return nil, err } bodyReader = bytes.NewBuffer(jsonData) } req, err := http.NewRequest(opt.Method, opt.URL, bodyReader) if err != nil { return nil, err } // Set default Content-Type untuk JSON req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") // Set custom headers for k, v := range opt.Headers { req.Header.Set(k, v) } // Set Bearer token kalau ada if opt.BearerToken != "" { req.Header.Set("Authorization", "Bearer "+opt.BearerToken) } // Set timeout client := &http.Client{ Timeout: opt.Timeout, } if client.Timeout == 0 { client.Timeout = 30 * time.Second } resp, err := client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() // Read all body (so we can decode or forward) bodyBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, err } // Forward error response directly if resp.StatusCode >= http.StatusBadRequest { // Try to decode as JSON first var errResult map[string]interface{} if json.Unmarshal(bodyBytes, &errResult) == nil { return errResult, fmt.Errorf("http error: %s", resp.Status) } return nil, fmt.Errorf("http error: %s", resp.Status) } // Decode JSON success response var result map[string]interface{} if err := json.Unmarshal(bodyBytes, &result); err != nil { return nil, err } return result, nil } func DefaultFHIRHeaders() map[string]string { return map[string]string{ "Content-Type": constant.ContentTypeFHIRJSON, "Accept": constant.ContentTypeFHIRJSON, } }