لجلب أسعار الذهب المباشرة في Node.js، أرسل طلب GET إلى api.goldprice.dev/v1/spot/XAU-USD-SPOT باستخدام fetch المدمجة، وضع مفتاح API في ترويسة X-API-Key. لا تحتاج إلى مكتبة HTTP. خزّن الاستجابة في Map لمدة 60 ثانية، واستخدم decimal.js لحساب الأسعار. تشمل الخطة المجانية 5,000 طلب شهريا دون بطاقة ائتمان. اختُبر في يوليو 2026 على Node 22 LTS.
احصل على مفتاح API من goldprice.dev
أنشئ حسابا مجانيا على goldprice.dev/onboarding. بعد تأكيد بريدك الإلكتروني، تعرض لوحة التحكم مفتاحا يبدأ بـ ga_live_. احفظه في متغير بيئة:
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_hereتشمل الخطة المجانية 5,000 طلب شهريا وأسعار الذهب الفورية بـ 31 عملة. لا تحتاج إلى بطاقة ائتمان.
ثبّت decimal.js
يتضمن Node 18+ الدالة fetch، فلا تحتاج إلى عميل HTTP. الاعتماد الوحيد هو decimal.js للحساب الدقيق للأسعار وتجنب أخطاء الدقة مع نوع Number في JavaScript. ثبّته:
npm install decimal.jsاكتب عميل goldprice
احفظ هذا الكود باسم goldprice.mjs. تخزّن الدالة spot() كل رمز في Map لمدة 60 ثانية، وتعيد المحاولة حتى 3 مرات عند 429 بتأخير متزايد أسيا، وتعيد الأسعار بنوع Decimal. أسعار الشراء والبيع اختيارية ومتاحة للخطط المدفوعة فقط، وتكون null عند غيابها.
// node: goldprice.mjs// curl-equivalent: https://api.goldprice.dev/v1/spot/XAU-USD-SPOTimport Decimal from "decimal.js";const API_BASE = "https://api.goldprice.dev";const API_KEY = process.env.GOLDPRICE_API_KEY;if (!API_KEY) { throw new Error("GOLDPRICE_API_KEY not set");}const TTL_MS = 60_000;const cache = new Map();/** Fetch live spot price. Cached 60s per symbol, retries 3x on 429. */export async function spot(symbol = "XAU-USD-SPOT") { const cached = cache.get(symbol); if (cached && cached.expiresAt > Date.now()) { return cached.data; } let lastErr; for (let attempt = 0; attempt < 3; attempt++) { const res = await fetch(`${API_BASE}/v1/spot/${symbol}`, { headers: { "X-API-Key": API_KEY }, signal: AbortSignal.timeout(5000), }); if (res.status === 429) { lastErr = new Error("goldprice: 429 rate limited"); const backoffMs = 2 ** attempt * 1000; // 1s, 2s, 4s await new Promise((resolve) => setTimeout(resolve, backoffMs)); continue; } if (!res.ok) { throw new Error(`goldprice: unexpected status ${res.status}`); } const raw = await res.json(); const data = { symbol: raw.symbol, quoteCurrency: raw.quote_currency, price: new Decimal(raw.price), bid: raw.bid == null ? null : new Decimal(raw.bid), ask: raw.ask == null ? null : new Decimal(raw.ask), isStale: raw.is_stale, computedAt: raw.computed_at, }; cache.set(symbol, { data, expiresAt: Date.now() + TTL_MS }); return data; } throw lastErr;}شغّل الكود
استورد الوحدة واستدعِ spot(). يرسل الاستدعاء الأول طلبا إلى API. خلال 60 ثانية، تعيد الاستدعاءات التالية قيمة Decimal المخزّنة دون اتصال بالشبكة. إعادة تشغيل العملية تمسح التخزين المؤقت لأنه داخل العملية فقط. استخدم Redis لمشاركته بين العمليات.
import { spot } from "./goldprice.mjs";const r = await spot("XAU-USD-SPOT");console.log(`${r.symbol}-${r.quoteCurrency}: ${r.price} (computed ${r.computedAt})`);// XAU-USD: 4012.75 (computed 2026-10-23T07:00:18.221118+00:00)غيّر العملة أو المعدن
صيغة الرموز هي METAL-CURRENCY-SPOT. مرّر رمزا بأي من العملات الفورية الـ 31 إلى spot(). يُخزّن كل رمز مستقلا في Map. لوحة تحكم تستعلم عن 5 رموز كل 60 ثانية ترسل 5 طلبات API في الدقيقة عند غياب التخزين المؤقت، و0 عند توفره.
// USD spot, defaultawait spot("XAU-USD-SPOT");await spot("XAU-INR-SPOT");await spot("XAU-EUR-SPOT");// Silver in USDawait spot("XAG-USD-SPOT");النتيجة المتوقعة
{ "symbol": "XAU", "quote_currency": "USD", "unit": "troy_ounce", "contract_type": "spot", "price": "4012.75", "is_stale": false, "computed_at": "2026-10-23T07:00:18.221118+00:00"}يعرض الإخراج القياسي سطرا واحدا: الرمز، وعملة التسعير، والسعر بنوع Decimal من decimal.js، والطابع الزمني computedAt بصيغة ISO 8601. يستخدم الكود اللاحق الكائن العادي الذي تعيده spot().
أخطاء شائعة
| الرمز | ما يظهر لك | الحل |
|---|---|---|
| 401 | ظهور goldprice: unexpected status 401 عند الاستدعاء الأول | مفتاح API مفقود أو غير صالح. تحقق من ضبط المتغير: echo $GOLDPRICE_API_KEY. إن كان فارغا، أعد تصدير المفتاح من لوحة التحكم. تطرح الوحدة خطأ عند استيرادها إذا كان متغير البيئة فارغا، فيظهر الخلل فورا قبل تنفيذ الطلب. |
| 429 | تعيد المحاولات الثلاث مع التأخير الرمز 429، ثم يُرفض استدعاء spot() | بلغت حد الطلبات في الدقيقة. يمنع التخزين المؤقت لمدة 60 ثانية ذلك عند الاستعلام المنتظم. إذا وصلت طلبات لرموز مختلفة دفعة واحدة، فوزّعها زمنيا. للاستخدام المكثف المستمر، راجع الخطط المدفوعة في /pricing. |
| N/A | تبدو الأسعار صحيحة، لكن تظهر فروق طفيفة بعد تكرار العمليات الحسابية | يستخدم Number في JavaScript الفاصلة العائمة وفق IEEE-754: 0.1 + 0.2 === 0.30000000000000004. أسعار الذهب لها 2 منازل عشرية، لذا يسبب جمع آلاف القيم باستخدام Number أخطاء بمقدار نقاط أساس. أبقِ الأسعار بنوع Decimal من decimal.js أثناء الحساب، ولا تستدعِ .toString() أو .toNumber() إلا عند العرض أو التسلسل. |
خطوات إضافية
- احتفظ بالتخزين المؤقت بين العمليات: استبدل
Mapبتخزين يعتمد على Redis لتتشارك العمليات العاملة السعر المخزّن - أضف دالة
bars()لاستدعاء/v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=...واستخدم السلسلة في اختبار بأثر رجعي - اربط العميل بمسار Express أو Fastify لتقديمه داخليا للخدمات التي لا تستخدم Node
- اجمع الطلبات المتزامنة للرمز نفسه عند غيابه من التخزين المؤقت، لتنفّذ دفعة الاستدعاءات طلب جلب واحدا
- أضف مقاييس Prometheus لنسبة إصابات التخزين المؤقت، وزمن الاستجابة p50/p95، وعدد محاولات الإعادة عند 429