Yimaru-BackEnd/internal/services/currency/fetcher.go

70 lines
1.6 KiB
Go

package currency
import (
"Yimaru-Backend/internal/domain"
"context"
"encoding/json"
"fmt"
"net/http"
"time"
)
type FixerFetcher struct {
apiKey string
baseURL string
httpClient *http.Client
}
func NewFixerFetcher(apiKey string, baseURL string) *FixerFetcher {
return &FixerFetcher{
apiKey: apiKey,
baseURL: baseURL,
httpClient: &http.Client{Timeout: 10 * time.Second},
}
}
type fixerResponse struct {
Success bool `json:"success"`
Base string `json:"base"`
Date string `json:"date"`
Rates map[string]float64 `json:"rates"`
}
func (f *FixerFetcher) FetchLatestRates(ctx context.Context, baseCurrency domain.IntCurrency) (map[domain.IntCurrency]float64, error) {
url := fmt.Sprintf("%s/latest?base=%s", f.baseURL, baseCurrency)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("apikey", f.apiKey)
resp, err := f.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to fetch rates: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
var result fixerResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}
if !result.Success {
return nil, fmt.Errorf("api returned unsuccessful response")
}
rates := make(map[domain.IntCurrency]float64)
for currency, rate := range result.Rates {
rates[domain.IntCurrency(currency)] = rate
}
return rates, nil
}