Case Study/生產環境案例研究

goldprice.dev 點樣用本幣定價黃金

goldprice.dev 點樣結合美元金屬價格同 exchangerate.dev 嘅外匯匯率,提供本幣金價,同時唔會掩蓋數據新舊嘅界線。

MMexchangerate.dev·Jul 16, 2026·7 分鐘閱讀

goldprice.dev 同 exchangerate.dev 係由同一間公司營運嘅姊妹產品。喺生產環境入面,goldprice.dev 負責金屬價格嘅合約,而 exchangerate.dev 就為受支援嘅浮動貨幣提供外匯部分。呢條界線好重要:一個本幣金價包含兩個市場觀察值,其中一個新鮮唔代表另一個都新鮮。

Key points
goldprice.dev 負責金屬價格同公開嘅兌換回應;exchangerate.dev 就提供外匯部分。
公開嘅 goldprice.dev /v1/convert 端點,提供單一請求嘅生產環境路徑。
如果開發人員需要可稽核嘅數據來源鏈,可以分開攞返兩個 API。
將黃金嘅 computed_at,同外匯嘅 data_updated_attimestampsourcemarket_session,分開儲存。
兌換後嘅價格只係指示性市場價值,並非可執行嘅交易商或結算報價。

生產環境嘅界線

goldprice.dev 由一個美元金屬觀察值開始。exchangerate.dev 就為受支援嘅浮動貨幣,提供相應嘅「美元兌本幣」外匯觀察值。之後 goldprice.dev 負責埋金屬專屬嘅兌換合約,包括單位、受支援嘅代碼、驗證,同最終回應。

呢個係一個公開披露嘅姊妹產品整合,並非獨立客戶嘅背書。作為案例研究,佢嘅價值在於運作層面:外匯 API 提供真實嘅生產環境數據部分,而使用方產品就繼續負責自己嘅領域。

兌換公式

黃金通常以「每金衡盎司美元」報價。本地顯示通常需要「每克貨幣金額」。要先換算重量,再套用美元匯率:

formula · USD/oz to local currency/gramcopy
const GRAMS_PER_TROY_OZ = 31.1035;

function localGoldPerGram(usdPerTroyOz, usdToLocalRate) {
  return (usdPerTroyOz / GRAMS_PER_TROY_OZ) * usdToLocalRate;
}

重量常數係固定嘅。但兩個市場輸入值就唔係:金價報價同外匯匯率,各自都有自己嘅觀察時間同新鮮度規則。

單一請求嘅生產環境路徑

對於呼叫方嚟講,生產環境嘅界線就係 goldprice.dev `/v1/convert`。呢個端點喺背後結合埋金屬同外匯兩個部分,喺一個懂得金屬嘅端點入面,而且唔需要 API key。以下呢個例子,查詢一克黃金以印尼盾計算嘅價值:

javascript · one-request conversioncopy
const params = new URLSearchParams({
  from: "XAU",
  to: "IDR",
  amount: "1",
  unit: "gram",
});

const response = await fetch(
  `https://api.goldprice.dev/v1/convert?${params}`,
);

if (!response.ok) {
  throw new Error(`goldprice.dev returned ${response.status}`);
}

const conversion = await response.json();
console.log(conversion.result, conversion.to, conversion.timestamp);

呢條路徑令呼叫方合約保持精簡:一個請求、一個金額、一個金屬單位,同一種目標貨幣。佢單一嘅 timestamp 唔可以獨立證明兩個市場部分嘅新鮮度,所以如果使用方一定要稽核外匯新鮮度,就應該用下面嗰條雙腿路徑。

可稽核嘅雙腿整合

如果你需要保留每個來源嘅時間戳、獨立快取輸入值,或者要解釋邊一個部分嘅數據已經過時,就應該分開攞返兩個 API。goldprice.dev spot 提供「每金衡盎司美元」金價;exchangerate.dev 就提供「美元兌本幣」匯率。

javascript · explicit gold and FX legscopy
const GRAMS_PER_TROY_OZ = 31.1035;

async function getGoldInCurrencies(currencies) {
  const symbols = currencies.join(",");
  const [spotResponse, fxResponse] = await Promise.all([
    fetch("https://api.goldprice.dev/v1/spot/XAU-USD-SPOT"),
    fetch(`https://api.exchangerate.dev/v1/latest/USD?symbols=${symbols}`),
  ]);

  if (!spotResponse.ok || !fxResponse.ok) {
    throw new Error("A market-data request failed");
  }

  const spot = await spotResponse.json();
  const fx = await fxResponse.json();
  const usdPerGram = Number(spot.price) / GRAMS_PER_TROY_OZ;

  return {
    goldComputedAt: spot.computed_at,
    fxDataUpdatedAt: fx.data_updated_at,
    fxResponseTimestamp: fx.timestamp,
    fxSource: fx.source,
    fxMarketSession: fx.market_session,
    prices: Object.fromEntries(
      currencies.map((currency) => [
        currency,
        usdPerGram * Number(fx.rates[currency]),
      ]),
    ),
  };
}

const result = await getGoldInCurrencies(["EUR", "IDR", "JPY"]);
回應時間戳唔等於市場時間戳
請保留 spot.computed_at 作為黃金觀察值,同埋 fx.data_updated_at 作為最舊嗰個有份貢獻嘅外匯觀察值。外匯嘅 timestamp 係回應建立嗰刻嘅時間;source 同 market_session 就補充埋數據類別同交易時段嘅背景。唔好用 Date.now() 去取代呢啲欄位。

點解兩個服務會保持分開

呢個整合並冇將 exchangerate.dev 變成成個金價引擎。佢仍然只係外匯層。保持呢條界線清晰,就可以防止貨幣新鮮度、金屬新鮮度,同產品專屬嘅兌換規則,全部混埋做一個模糊嘅數值。

  • goldprice.dev 可以提供一個細小、金屬專屬嘅介面,唔使呼叫方自己組裝返成條常用路徑。
  • exchangerate.dev 就保持一個通用嘅外匯合約,喺金屬領域以外都用得著。
  • 對稽核有要求嘅使用方,可以獨立攞返同儲存兩個觀察值。
  • 每個服務都可以用返自己市場數據嘅詞彙,去回報失敗同新鮮度。

明確處理過時或缺失嘅部分

如果任何一個輸入值缺失、為零、唔係數字,或者超出咗你產品可接受嘅新鮮度範圍,合併後嘅價格就唔應該再用。除非介面有標明返原本嘅觀察時間,否則先保留最後一個有效數值。

  • 喺做任何運算之前,先檢查兩個 HTTP 回應。
  • 拒絕非有限值或非正數嘅價格同匯率。
  • 為黃金同外匯分別設定新鮮度門檻。
  • market_session: weekend 當成背景資訊,而唔係證明一個延續使用嘅匯率仍然係最新。
  • 喺兌換錯誤入面,記錄返貨幣對,同兩個底層觀察時間。

顯示時先四捨五入,運算時唔好

喺乘法運算入面保留全部精度,將最終小數位數交返俾顯示嘅地區設定決定。Intl.NumberFormat 可以處理貨幣符號同分組,而唔會改變底層數值:

javascript · locale-aware displaycopy
function formatPrice(amount, currency, locale) {
  return new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
  }).format(amount);
}

console.log(formatPrice(result.prices.IDR, "IDR", "id-ID"));
console.log(formatPrice(result.prices.JPY, "JPY", "ja-JP"));

將結果當成指示性數值嚟用

計算出嚟嘅市場價值,並唔係一個金幣或金條嘅零售價。交易商溢價、稅項、加工費、付款手續費,同可執行嘅外匯價差,都唔喺呢條公式嘅範圍之內。除非你嘅應用程式加返一個真實嘅交易商報價同其商業條款,否則就應該將輸出標示為指示性數值。

呢個案例研究證明咗啲乜

goldprice.dev 係第一方證據,證明 exchangerate.dev 有能力為生產環境嘅定價流程提供外匯部分。呢個並非獨立嘅社會認證。真正有用嘅證明範圍比較窄,但可以重現:開發人員可以呼叫返同一啲公開產品,保留兩個觀察時間,自己驗證條算式。

MM
exchangerate.dev
為開發人員撰寫嘅生產環境整合筆記。

Keep reading

Reference讀懂 source 同 market_sessionRead Tutorial喺 JavaScript 同 Node.js 入面做貨幣兌換Read Guide指示性同可執行外匯匯率嘅分別Read