Go 표준 라이브러리만으로 안정적인 연동이 가능합니다. JSON을 디코드하기 전에 HTTP 상태를 확인하고 출처와 업데이트 시간을 함께 저장하세요.
- 타입 기반 클라이언트 만들기: net/http, context, encoding/json으로 여러 통화를 한 번에 요청합니다. EXCHANGERATE_API_KEY가 있을 때만 Bearer를 추가하세요.
- timeout으로 호출하기: context.WithTimeout으로 멈춘 연결이 worker를 계속 점유하지 않게 하세요. 운영에서는 http.Client를 재사용하세요.
- 오류와 최신성 처리하기: 401은 키를 고쳐야 하고 429는 요청을 줄여야 합니다. source, market_session, data_updated_at을 보존하고 브라우저에 키를 노출하지 마세요.
타입 기반 클라이언트 만들기
net/http, context, encoding/json으로 여러 통화를 한 번에 요청합니다. EXCHANGERATE_API_KEY가 있을 때만 Bearer를 추가하세요.
go · main.go
package mainimport ( "context" "encoding/json" "fmt" "net/http" "log" "os" "regexp" "strings" "time")type Latest struct { Base string `json:"base"` Source string `json:"source"` MarketSession string `json:"market_session"` UpdatedAt time.Time `json:"data_updated_at"` Sources map[string]string `json:"sources"` EffectiveAt map[string]string `json:"effective_at"` Rates map[string]json.Number `json:"rates"`}func LatestRates(ctx context.Context, base string) (Latest, error) { base = strings.ToUpper(base) if !regexp.MustCompile("^[A-Z]{3}$").MatchString(base) { return Latest{}, fmt.Errorf("invalid base currency: %q", base) } url := "https://api.exchangerate.dev/v1/latest/" + base + "?symbols=EUR,GBP,JPY" req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return Latest{}, err } if key := os.Getenv("EXCHANGERATE_API_KEY"); key != "" { req.Header.Set("Authorization", "Bearer "+key) } client := &http.Client{Timeout: 5 * time.Second, CheckRedirect: func(_ *http.Request, _ []*http.Request) error { return http.ErrUseLastResponse }} res, err := client.Do(req) if err != nil { return Latest{}, err } defer res.Body.Close() if res.StatusCode < 200 || res.StatusCode >= 300 { return Latest{}, fmt.Errorf("exchange rate API: HTTP %s", res.Status) } var out Latest if err := json.NewDecoder(res.Body).Decode(&out); err != nil { return Latest{}, err } return out, nil}func main() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() latest, err := LatestRates(ctx, "USD") if err != nil { log.Fatal(err) } fmt.Println(latest.Rates["EUR"], latest.Sources["EUR"], latest.EffectiveAt["EUR"])}timeout으로 호출하기
shell · run main.go
go run main.go오류와 최신성 처리하기
401은 키를 고쳐야 하고 429는 요청을 줄여야 합니다. source, market_session, data_updated_at을 보존하고 브라우저에 키를 노출하지 마세요.
환율의 맥락을 함께 저장하세요
일일 보고서는 하루 한 번, 운영 대시보드는 한 시간마다 호출하면 됩니다. 429가 오면 즉시 재시도하지 말고 주기를 줄이세요.
- 출처와 시간과 함께 환율을 저장합니다.
- 자동화와 분석에 사용합니다.
- 실행 가능한 가격으로 취급하지 않습니다.