ガイドチュートリアル

JavaScript と Node.js で通貨を換算する

fetch でレートを取得し、JSON の値を使って換算します。金額の計算と表示には currency.js を組み合わせます。

2026年10月1日 · 6分で読めます

ブラウザでは匿名リクエストから始められます。Node.js やサーバーではキーを環境変数に置き、レートの source と観測時刻も保存します。

  • fetch は Node 18+、Deno、Bun、現代のブラウザで使える。
  • ブラウザにアカウントキーを含めない。
  • currency.js は金額計算と表示に使い、レート取得とは分ける。
  • HTTP エラーを確認し、429 では Retry-After に従う。
  • source と effective_at を表示してデータの時点を説明する。

最初のコール、キー不要

Node 18やモダンブラウザにはfetchが最初から入っている。EURレートを読むにはawait 1回で足りる:

匿名コールはIPアドレスごとに上限があるため、簡単な試験を超えたら無料キーに移行する。

キーとエラーハンドリングを追加する

キーはAuthorizationヘッダーのベアラートークンとして渡す。res.okを確認し、異常ステータスではthrowしてエラーを早期に表面化させる:

X-API-Key: exr_live_...ヘッダーも受け付けられる。Authorizationヘッダーを設定できないプラットフォーム(一部のサーバーレスランタイム、Zapierなどのノーコードツール)向けだ。

金額を換算する

直接換算するには/v1/convert/{from}/{to}/{amount}を呼ぶ。レスポンスは1往復でレートと換算額の両方を返す:

convertエンドポイントもlatestと同じsourceとmarket_sessionフィールドを返すため、レートの種別とインターバンクの取引週が開いているかをユーザーに示せる。

sourceとmarket_sessionを理解する

表示する通貨については、sources[currency]でデータの種類、effective_at[currency]で観測時刻を確認してください。sourceはレスポンス全体で最も更新頻度の低いデータを表します。market_sessionは市場の取引時間帯、timestampはレスポンスの生成時刻であり、価格の観測時刻ではありません。

フィールド値意味動くタイミング
source: live参考用のスポット市場レート取引週の日中(約60秒間隔)
source: ecb_daily欧州中央銀行の参照フィックス営業日に1回(16:00 CET頃)
source: market_dailyECBなしの保存終値日次市場
market_session: weekend土曜または日曜(インターバンク休場)参照フィックスは金曜値を維持、ライブフィードは停止

data_updated_atフィールドは元のレートが最後に書き込まれた時刻を示す。timestampはレスポンスが生成された時刻だ。この2つを合わせて、値のキャッシュ方法と表示方法を決められる。

インディケーティブレートのみ

これらのレートは参照、分析、表示向けに公開されている。ディーリングクォートではなく、取引や送金の決済に使ってはならない。すべてのレスポンスのnoticeフィールドにその旨が記載されている。

無料枠の上限

月間利用枠は毎月1日00:00 UTCにリセットされます。429の場合はRetry-Afterに従って再試行してください。

  • 月5,000コール
  • 毎分10リクエスト
  • クレジットカード不要
  • /v1/latest、/v1/convert、/v1/range、/v1/{date}/{base}をカバー

金額を計算して表示する

currency.js は金額、精度、表示を扱うライブラリです。先に API からレートを取得し、その後で金額を掛けます。

javascript · no key
const response = await fetch("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP", {  signal: AbortSignal.timeout(10_000),});if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);const data = await response.json();console.log(data.rates.EUR);console.log(data.sources.EUR, data.effective_at.EUR);console.log(data.market_session);
javascript · authenticated call with error handling
// Node.js server only. Never put an account key in browser code.const KEY = process.env.EXCHANGERATE_API_KEY;if (!KEY) throw new Error("Set EXCHANGERATE_API_KEY on your server");async function getLatest(base = "USD") {  const response = await fetch(`https://api.exchangerate.dev/v1/latest/${encodeURIComponent(base)}`, {    headers: { Authorization: `Bearer ${KEY}` },    redirect: "error",    signal: AbortSignal.timeout(10_000),  });  if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);  return response.json();}const data = await getLatest("USD");console.log(data.rates.GBP, data.effective_at.GBP);
javascript · convert 100 USD to EUR
// Node.js server only.const KEY = process.env.EXCHANGERATE_API_KEY;if (!KEY) throw new Error("Set EXCHANGERATE_API_KEY on your server");const response = await fetch("https://api.exchangerate.dev/v1/convert/USD/EUR/100", {  headers: { Authorization: `Bearer ${KEY}` },  redirect: "error",  signal: AbortSignal.timeout(10_000),});if (!response.ok) throw new Error(`HTTP ${response.status}; Retry-After: ${response.headers.get("Retry-After")}`);const data = await response.json();console.log(data.rate, data.converted);
JavaScript · currency.js
import currency from "currency.js";const response = await fetch("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR", {  signal: AbortSignal.timeout(10_000),});if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();const rate = data.rates.EUR;if (!Number.isFinite(rate) || rate <= 0) throw new Error("Invalid rate");const euros = currency("100.00", { precision: 2, symbol: "€" }).multiply(rate);console.log(euros.format());

よくある質問

JavaScriptでこのAPIを使うのにバンドラーや追加パッケージは必要か?

不要。グローバルのfetch関数はNode 18+、Deno、Bun、すべてのモダンブラウザに組み込まれている。await fetch(...)とres.json()の1行で最初のコールができ、サードパーティのHTTPライブラリは要らない。

fetchリクエストでAPIキーはどう渡す?

Authorizationヘッダーにベアラートークンとして送る:{ "Authorization": "Bearer exr_live_..." }。X-API-Keyヘッダーもエイリアスとして受け付けられ、カスタムのAuthorizationヘッダーを設定できないプラットフォームで役立つ。

/v1/latestと/v1/convertの違いは?

latestエンドポイントは選んだベース通貨に対する144通貨すべてのレートを返す。convertエンドポイントは換算元通貨、換算先通貨、任意の金額を受け取り、レートと換算後の値を1コールで返す。1ペアだけ必要で計算結果も欲しいときはconvertを使う。

このレートで支払い処理や取引の決済はできるか?

できない。レートはインディケーティブ値で、参照・表示・分析専用だ。ディーリングクォートではない。すべてのレスポンスにその旨を示すnoticeフィールドが含まれる。決済に適用されるレートは決済事業者に確認すること。

関連記事

無料のAPIキーで始める

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

無料キーを取得