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 مسار الإنتاج بطلب واحد.
يمكن للمطورين استدعاء كلتا الواجهتين بشكل منفصل عندما يحتاجون إلى سلالة بيانات قابلة للتدقيق.
خزِّن حقل computed_at الخاص بالذهب وحقول data_updated_at وtimestamp وsource وmarket_session الخاصة بسعر الصرف كلًا على حدة.
الأسعار المحوَّلة قيم سوقية إرشادية، وليست عروض أسعار تنفيذية من تجار أو أسعار تسوية.

الحد الفاصل في الإنتاج

يبدأ goldprice.dev برصد للمعدن بالدولار الأمريكي. يوفر exchangerate.dev رصد سعر الصرف المقابل من الدولار الأمريكي إلى العملة المحلية للعملات العائمة المدعومة. بعد ذلك يملك goldprice.dev عقد التحويل الخاص بالمعدن، بما في ذلك الوحدات والرموز المدعومة والتحقق من الصحة والاستجابة النهائية.

هذا تكامل بين منتجين شقيقين مُفصَح عنه، وليس تزكية من عميل مستقل. قيمته كدراسة حالة عملية: توفر واجهة FX 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. يطلب هذا المثال قيمة جرام واحد من الذهب بالروبية الإندونيسية:

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 الوحيد فيه لا يُثبت بشكل مستقل طزاجة كلا الشقين السوقيين، لذا ينبغي للمستهلكين الذين يحتاجون إلى تدقيق طزاجة سعر الصرف استخدام مسار الشقين أدناه.

التكامل القابل للتدقيق بشقين منفصلين

اطلب من كلتا الواجهتين عندما تحتاج إلى الاحتفاظ بختم زمني لكل مصدر، أو تخزين المدخلات مؤقتًا كلٌّ على حدة، أو توضيح أي الشقين أصبح غير طازج. يوفر سعر goldprice.dev الفوري سعر الذهب بالدولار لكل أونصة تروي؛ ويوفر 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 لأقدم رصد سعر صرف مساهم. الختم الزمني لسعر الصرف هو وقت بناء الاستجابة؛ ويضيف source وmarket_session سياق فئة البيانات والجلسة. لا تستبدل هذه الحقول بـ Date.now().

لماذا تبقى الخدمتان منفصلتين

هذا التكامل لا يحوّل exchangerate.dev إلى محرك تسعير الذهب بأكمله. فهو يبقى طبقة سعر الصرف. والحفاظ على هذا الحد الفاصل صريحًا يمنع تداخل طزاجة العملة وطزاجة المعدن وقواعد التحويل الخاصة بكل منتج في قيمة واحدة غامضة.

  • يمكن لـ goldprice.dev أن يعرض واجهة صغيرة خاصة بالمعدن دون إلزام المستدعين بتجميع المسار الشائع بأنفسهم.
  • يحتفظ exchangerate.dev بعقد سعر صرف عام مفيد خارج نطاق المعادن.
  • يمكن للمستهلكين الحساسين للتدقيق جلب كلا الرصدين وتخزينهما كلٌّ على حدة.
  • يمكن لكل خدمة الإبلاغ عن الأعطال والطزاجة باستخدام مفردات بيانات سوقها الخاصة.

تعامل صراحةً مع الشقوق غير الطازجة أو المفقودة

لا ينبغي لسعر مُركَّب أن يصمد إذا كان أحد المدخلين مفقودًا أو صفرًا أو غير رقمي أو خارج نافذة الطزاجة المقبولة في منتجك. احتفظ بآخر قيمة صالحة فقط إذا كانت الواجهة تُصنّفها بأوقات رصدها الأصلية.

  • تحقق من كلتا استجابتَي HTTP قبل إجراء أي عملية حسابية.
  • ارفض الأسعار وأسعار الصرف غير المنتهية أو غير الموجبة.
  • حدِّد عتبات طزاجة منفصلة للذهب وسعر الصرف.
  • تعامل مع market_session: weekend باعتباره سياقًا، لا دليلًا على أن سعرًا مرحّلًا لا يزال حاليًا.
  • سجِّل زوج العملات وكِلا وقتَي الرصد الأساسيين مع أخطاء التحويل.

قرّب الأرقام للعرض، لا أثناء الحساب

احتفظ بالدقة الكاملة طوال عملية الضرب، واترك لغة العرض (locale) تحدد العدد النهائي للمنازل العشرية. تتولى 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.jsRead Guideسعر FX الإرشادي مقابل القابل للتنفيذRead