الإعدادات

اضبط عميل listingsapi-js: آلية تحديد مفتاح API، وتجاوز عنوان URL الأساسي، والمهلات، وإعادة المحاولة التلقائية.

خيارات المنشئ

يقبل ListingsAPI كائن خيارات واحدًا اختياريًا بالكامل:

الخيارالنوعمطلوبالقيمة الافتراضيةالوصف
apiKeystringلاprocess.env.LISTINGSAPI_KEYمفتاح Listings API الخاص بك. عند عدم تمريره، يقرأ العميل متغير البيئة LISTINGSAPI_KEY ويطرح AuthenticationError إذا لم يُضبط المفتاح في أي من الموضعين.
baseUrlstringلاhttps://listingsapi.comتغيير مضيف API، وهو مفيد عند استخدام خوادم وسيطة أو بيئات تجهيز. تُزال الشرطات المائلة في النهاية تلقائيًا.
timeoutnumberلا240000مهلة كل طلب بالمللي ثانية، وتُطبَّق باستخدام AbortSignal.timeout.
maxRetriesnumberلا2إعادة المحاولة تلقائيًا عند بلوغ حدود معدل الطلبات أو حدوث أخطاء في الخادم أو أعطال في الشبكة. لعمليات القراءة فقط؛ لا تُعاد محاولة عمليات الكتابة مطلقًا. اضبط القيمة على 0 لتعطيل إعادة المحاولة.
TypeScript
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI(); // reads LISTINGSAPI_KEY from env // Every default spelled out:const custom = new ListingsAPI({apiKey: process.env.LISTINGSAPI_KEY,baseUrl: 'https://listingsapi.com',timeout: 240000,   // 4 minutes per attemptmaxRetries: 2,     // up to 3 attempts total});

تحديد مفتاح API

لا تضع المفتاح مباشرةً في الشيفرة المصدرية مطلقًا. يقرأ المنشئ الذي يُستدعى دون وسائط LISTINGSAPI_KEY من البيئة:

Shell
export LISTINGSAPI_KEY="your-api-key"
TypeScript
const client = new ListingsAPI();

أو مرّر مفتاحًا جلبته من مدير أسرار:

TypeScript
import { getSecret } from './secrets.js'; const apiKey = await getSecret('LISTINGSAPI_KEY');const client = new ListingsAPI({ apiKey });

إذا لم يُعثر على مفتاح في أي من الموضعين، يطرح المنشئ AuthenticationError فورًا، قبل إرسال أي طلب.

تغيير عنوان URL الأساسي

وجّه العميل إلى خادم وسيط داخلي أو بيئة تجهيز:

TypeScript
const client = new ListingsAPI({baseUrl: 'https://listings-proxy.internal.example.com',});

تُزال الشرطات المائلة في النهاية تلقائيًا، لذا يعمل 'https://listingsapi.com/' و'https://listingsapi.com' بالطريقة نفسها.

المهل

تُغلَّف كل محاولة داخليًا باستخدام AbortSignal.timeout(timeout) (Node 18+)، لذا لا تحتاج إلى إحاطة استدعاءات SDK باستخدام AbortController خاص بك. المهلة الافتراضية هي 240000 مللي ثانية (4 دقائق) لكل محاولة.

تُعدّ المحاولة التي انتهت مهلتها فشلًا في الاتصال: يعيد العميل المحاولة ما دامت هناك محاولات متبقية، ويطرح APIConnectionError عند الفشل النهائي. قلّل المهلة للمسارات الحساسة لزمن الاستجابة:

TypeScript
const client = new ListingsAPI({ timeout: 15000 }); // 15 s per attempt

إعادة المحاولة تلقائيًا

يعيد العميل محاولة الطلبات التي تتلقى استجابات بالحالات 429 و500 و502 و503 و504، وكذلك عند حدوث أعطال على مستوى الشبكة (أخطاء DNS ورفض الاتصالات وانتهاء المهل)، وذلك لطرق HTTP الآمنة فقط: GET وHEAD وOPTIONS. بدءًا من 0.3.2، تُرسل عملية الكتابة (POST وDELETE) مرة واحدة فقط ويُبلَّغ عن فشلها فورًا. مع الإعداد الافتراضي maxRetries: 2، تُجرى لكل عملية قراءة 3 محاولات كحد أقصى.

لا تدعم واجهة API بالإصدار v4 ‏Idempotency-Key ولا تكتشف عمليات الكتابة المتكررة، لذا قد تكون عملية الكتابة التي تنتهي مهلتها أو تُرجع 5xx قد حُفظت بالفعل. إعادة محاولتها دون تحقق ستنشئ موقعًا أو منشورًا أو ردًا على تقييم للمرة الثانية. اقرأ السجل مجددًا باستخدام مفتاح تتحكم فيه قبل تكرار عملية الكتابة.

مدة الانتظار قبل كل إعادة محاولة:

  1. إذا احتوت الاستجابة على ترويسة Retry-After تتضمن عددًا موجبًا من الثواني، ينتظر العميل تلك المدة بالضبط.
  2. وإلا، تزداد مدة الانتظار أُسّيًا: 500 مللي ثانية قبل إعادة المحاولة الأولى، ثم تتضاعف مع كل إعادة محاولة بعدها (1 ثانية، ثم 2 ثانية، وهكذا).

تُعاد المحاولة عند أعطال الشبكة فورًا دون انتظار. عند نفاد المحاولات، تتحول الاستجابة الأخيرة إلى خطأ ذي نوع محدد (RateLimitError وInternalServerError وغيرهما؛ راجع معالجة الأخطاء)، ويُطرح APIConnectionError إذا استمر عطل الشبكة بعد نفاد المحاولات.

TypeScript
// Fail fast and own the retry policy yourself:const client = new ListingsAPI({ maxRetries: 0 });

معرّفات المواقع

في كل موضع تقبل فيه SDK معرّف موقع، تُرمَّز المعرّفات الرقمية تلقائيًا إلى صيغة base64 التي تستخدمها API ‏(Location:<id>)، وتُمرَّر المعرّفات المرمَّزة مسبقًا دون تغيير. تُصدَّر الدالة المساعدة لتتمكن من الحصول على الصيغة المرمَّزة بنفسك إذا احتجت إليها:

TypeScript
import { encodeLocationId } from 'listingsapi-js'; encodeLocationId(16808);                  // 'TG9jYXRpb246MTY4MDg='encodeLocationId('TG9jYXRpb246MTY4MDg='); // returned as-is

تنسيق الترويسات

تُجرى المصادقة على كل طلب باستخدام:

Code
Authorization: API <your-key>Content-Type: application/json

تضبط SDK هذه الترويسات تلقائيًا في كل استدعاء. لا تحتاج إلى إعدادها.

إعداد مشروع TypeScript

صُممت SDK أساسًا للاستخدام مع TypeScript وتتضمن تعريفات الأنواع، لذا لا تحتاج إلى تثبيت حزمة @types منفصلة. ثبّت رقم الإصدار للحصول على نتائج بناء قابلة لإعادة الإنتاج:

Shell
npm install listingsapi-js@0.3.2

إعداد بسيط لـ tsconfig.json في مشروع Node 18+:

tsconfig.json
{"compilerOptions": {  "target": "ES2022",  "module": "Node16",  "moduleResolution": "Node16",  "strict": true,  "outDir": "dist"}}

لمشاريع ESM التي تحتوي على "type": "module" في package.json، استخدم "module": "Node16" و"moduleResolution": "Node16". ولمشاريع CJS، يعمل "module": "CommonJS" و"moduleResolution": "Node" دون مشكلة؛ تتضمن الحزمة نسختي البناء، وتحمّلها شيفرة CommonJS باستخدام const { ListingsAPI } = require('listingsapi-js').

الاستخدام دون TypeScript

يُحوَّل listingsapi-js إلى JavaScript عادي دون أي اعتماديات وقت التشغيل. يمكنك استيراده من ملف .js أو .mjs دون خطوة بناء:

script.mjs
import { ListingsAPI } from 'listingsapi-js'; const client = new ListingsAPI();const page = await client.fetchAllLocations({ first: 5 });for (const location of page.locations) {console.log(location.name, location.city); // Acme Dental Midtown}

الخطوات التالية