ガイドチュートリアル

Goのnet/httpで為替レートを取得する

net/http、タイムアウト、環境変数の認証、更新情報を使った型付きGoクライアントを作る。

2026年9月8日 · 6分で読める

標準ライブラリだけで堅牢な連携ができる。JSONを読む前にHTTPエラーを処理し、レートとsource、market_session、更新時刻を一緒に保存する。

  • 型付きクライアントを作る: net/http、context、encoding/jsonで複数通貨を一度に取得する。EXCHANGERATE_API_KEYがある場合だけBearerを付ける。
  • タイムアウト付きで呼び出す: context.WithTimeoutで接続停止がワーカーを占有しないようにする。本番では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"])}

タイムアウト付きで呼び出す

shell · run main.go
go run main.go

エラーと鮮度を処理する

401は認証を直し、429は通信量を抑える。source、market_session、data_updated_atを残し、ブラウザやモバイルへキーを出さない。

レートの意味を一緒に保存する

日次レポートなら1日1回、運用画面なら1時間ごとを目安にする。429では即時リトライを増やさず、頻度を下げる。

  • レートとsource、更新時刻を保存する。
  • 自動化や分析の参考値として使う。
  • 約定可能な価格として扱わない。

よくある質問

SDKは必要ですか?

不要です。Go標準パッケージだけで実装できます。

キーはどこに置きますか?

サーバーのEXCHANGERATE_API_KEYに置き、コードには保存しません。

決済に使えますか?

いいえ。参考・分析用のインディケーティブなデータです。

429の後はどうしますか?

頻度を下げ、すぐに再試行せず、プランの制限を守ります。

関連記事

無料のAPIキーで始める

無料プランで月5,000リクエスト。クレジットカードは不要です。

無料キーを取得