PanduanTutorial

Mengambil kurs valas di Go dengan net/http

Buat klien Go bertipe dengan net/http, timeout, autentikasi dari environment, dan kolom waktu pembaruan untuk mengambil kurs dari exchangerate.dev.

8 Sep 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.

  • 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.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"])}

Panggil dengan timeout

shell · run main.go
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.

Pertanyaan

Perlu SDK?

Tidak, cukup paket standar Go.

Kunci disimpan di mana?

Di EXCHANGERATE_API_KEY pada server.

Bisa untuk settlement?

Tidak, ini data indikatif untuk aplikasi dan analisis.

Apa yang dilakukan setelah 429?

Kurangi jadwal, jangan langsung retry, dan patuhi batas paket.

Baca selanjutnya

Mulai dengan kunci API gratis

5.000 permintaan per bulan dengan paket gratis. Tanpa kartu kredit.

Dapatkan kunci gratis