70 lines
1.6 KiB
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
|
|
}
|