Tutorial/Mulai cepat Go

Mengambil kurs valas di Go dengan net/http

Buat klien Go bertipe dengan net/http, timeout, autentikasi dari environment, dan kolom waktu pembaruan.

ERexchangerate.dev·Sep 8, 2026·6 menit membaca

Pustaka standar Go sudah cukup. Periksa status HTTP sebelum membaca JSON dan simpan sumber, sesi pasar, serta waktu pembaruan bersama kurs.

Key points
Buat klien bertipe: Gunakan net/http, context, dan encoding/json untuk beberapa mata uang dalam satu permintaan. Tambahkan Bearer hanya jika EXCHANGERATE_API_KEY tersedia.
Panggil dengan timeout: context.WithTimeout mencegah koneksi macet menahan worker. Di produksi, gunakan http.Client yang dipakai ulang.
Tangani error dan kesegaran: 401 berarti perbaiki kunci; 429 berarti kurangi trafik. Simpan source, market_session, data_updated_at dan jangan tampilkan kunci di browser atau mobile.

Buat klien bertipe

Gunakan net/http, context, dan encoding/json untuk beberapa mata uang dalam satu permintaan. Tambahkan Bearer hanya jika EXCHANGERATE_API_KEY tersedia.

go · main.gocopy
package main

import (
  "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"])
}

Panggil dengan timeout

shell · run main.gocopy
go run main.go

Tangani error dan kesegaran

401 berarti perbaiki kunci; 429 berarti kurangi trafik. Simpan source, market_session, data_updated_at dan jangan tampilkan kunci di browser atau mobile.

Simpan konteks kurs
Laporan harian cukup sekali sehari, sedangkan dashboard operasional bisa tiap jam. Saat menerima 429, kurangi jadwal dan jangan membuat loop retry.
  • Simpan kurs bersama sumber dan waktu.
  • Gunakan untuk otomasi dan analisis.
  • Jangan perlakukan sebagai kuotasi eksekusi.
ER
exchangerate.dev
Panduan integrasi untuk developer.

Baca selanjutnya

ReferenceMulai cepat API kursBaca TutorialPythonBaca Referencesource / market_sessionBaca
Perbandingan LainnyaFixer vs exchangerate.devOpen Exchange Rates vs exchangerate.devCurrencylayer vs exchangerate.dev
PanduanReading source and market_session in your pipelineIndicative vs executable FX rates: what a rates API actually gives youECB reference rates, explained
Kurs LangsungEUR/USDGBP/USDUSD/JPY