指南教程

用 Go 的 net/http 获取汇率

使用 net/http、超时、环境变量认证和更新时间字段,构建类型明确的 Go 客户端,在服务器端获取 exchangerate.dev 汇率。

2026年9月8日 · 阅读约 6 分钟

Go 标准库就足够完成可靠集成。解析 JSON 前先检查 HTTP 状态,并把来源、市场时段和更新时间与汇率一起保存。

  • 创建类型明确的客户端: 用 net/http、context 和 encoding/json 一次请求多个币种。只有存在 EXCHANGERATE_API_KEY 时才发送 Bearer。
  • 使用超时调用: 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"])}

使用超时调用

shell · run main.go
go run main.go

处理错误和数据新鲜度

401 表示修复密钥,429 表示降低请求频率。保留 source、market_session、data_updated_at,也不要把密钥放进浏览器或移动端。

同时保留汇率上下文

日报可以每天调用一次,运营看板可以每小时调用一次。收到 429 时降低频率,不要立即制造重试风暴。

  • 把汇率与来源和时间一起保存。
  • 用于自动化、估算、报表和分析。
  • 不要当作可成交报价。

常见问题

需要 SDK 吗?

不需要,Go 标准库即可。

密钥放在哪里?

放在服务器环境变量 EXCHANGERATE_API_KEY 中,不要提交到代码。

能用于结算吗?

不能,这是用于应用、估算、报表和分析的参考数据。

收到 429 后怎么办?

降低请求频率,不要立即重试,并遵守套餐限制。

继续阅读

从免费API密钥开始

免费套餐每月提供5,000次请求。无需信用卡。

获取免费密钥