الدليل
الترقيم والترشيح
المعاملات page وpage_size وsort وorder وq وfilter[key] على كل قائمة، مع سقف العمق الذي يقصّ رقم الصفحة بصمت بدل أن يردّ خطأ.
كل نقطة قائمة في واجهة X-Radius تقرأ المعاملات الستة نفسها وتعيد الغلاف نفسه. تعلَّمها مرةً تعمل على المشتركين والجلسات والكروت والفواتير والمديرين وغيرها.
المعاملات
| المعامل | النوع | الافتراضي | ملاحظات |
|---|---|---|---|
page |
عدد صحيح | 1 |
يبدأ من واحد. والقيم دون الواحد تُتجاهل، لا تُرفض. |
page_size |
عدد صحيح | 50 |
يُقصّ إلى حد أقصى قدره 200. |
sort |
نص | حسب النقطة | لكل نقطة قائمة سماح خاصة بأعمدة الترتيب؛ والقيمة المجهولة ترتدّ إلى افتراضي تلك النقطة. |
order |
تعداد | desc |
يُقبل asc وdesc فقط؛ وما عداهما يُتجاهل. |
q |
نص | — | بحث حر. والأعمدة التي يغطيها تختلف بحسب النقطة وهي موثَّقة على كل واحدة. |
filter[key] |
نص | — | تضييق بنيوي، بصيغة الأقواس المربعة. والمفاتيح خاصة بكل نقطة. |
curl -s "https://acme.example.com/api/v1/users?page=2&page_size=100&sort=created_at&order=desc&filter[enabled]=true&q=ahmed" \
-H "Authorization: Bearer $XRADIUS_TOKEN"
والقيم خارج المدى تُقصّ لا تُرفض. فـpage_size بقيمة 9999 يصير 200، وorder
غير المفهوم يصير desc. وذلك مقصود، كي لا يتحول خطأ مطبعي عند العميل إلى
انفجار في الخادم — لكنه يعني أن معاملًا خاطئًا بصمت يبدو تمامًا كمعامل صحيح،
فاقرأ كتلة meta الراجعة بدل افتراض أن طلبك أُخذ حرفيًا.
المرشّحات خاصة بكل نقطة، لا عامة
لا يوجد سجل مرشّحات مركزي. فالمحلّل المشترك يحتفظ بكل filter[key] يجده نصًّا
معتمًا ويسلّم الحزمة إلى المعالج، الذي يتحقق من مفاتيحه هو وفق قائمته هو.
ونتيجتان:
- مفتاح مرشّح لا تعرفه النقطة يُتجاهل بصمت. فلا يردّ خطأً ولا يضيّق شيئًا. فإن بدا أن مرشّحًا لا يفعل شيئًا فتحقق من هجائه أولًا مقابل مفاتيح تلك النقطة الموثَّقة.
- أما المفتاح المعروف بقيمة غير قابلة للتحليل فيردّ عادةً
400 ERR_VALIDATION— فالتواريخ والمدَيات العددية يجري التحقق منها. فـ "يُتجاهل" و"يُرفض" كلاهما يحدث، وأيُّهما يقع يتوقف على ما إذا كان المفتاح معروفًا.
والتحديد الذي يحقنه الخادم يُضاف بعملية "و" فوق كل ما ترسله. فالمدير الذي لا
يملك رؤية على مستوى المستأجر يرى شجرته هو فقط، وfilter[parent_id] يشير خارجها
يضيّق داخل الشجرة بدل أن يوسّع خارجها. فلا تستطيع بلوغ صفوف موزّع آخر بصياغة
مرشّح.
كتلة meta
{
"data": [ { "id": 4711, "username": "ahmed" } ],
"meta": {
"page": 2,
"page_size": 100,
"total": 812,
"has_next": true
}
}
يُعاد page وpage_size كما حلّهما الخادم، بعد القصّ — فقارنهما بما
أرسلت. وtotal عدد صفوف المجموعة المرشَّحة كلها، لا الصفحة. وhas_next يُحسب
في الخادم؛ واشتقاقه بنفسك من total وpage_size هو خطأ الواحد الكلاسيكي عند
حدّ الصفحة الأخيرة، فاستعمل الحقل.
وتظهر ثلاثة حقول اختيارية على أقلية من النقاط:
aggregates— تجميعات عددية على المجموعة المرشَّحة كلها لا على الصفحة: مجاميع الفواتير، ومجاميع التقارير، وأرصدة دفتر الأستاذ الافتتاحية والختامية.truncated— على النقاط غير المرقَّمة القليلة التي تحمل سقف صفوف صلبًا فقط. وtrueتعني أن السقف بلغ وأن صفوفًا أُسقطت. أما النقطة المرقَّمة فتقول الشيء نفسه بـhas_next.cachedوcached_at— تضبطهما نقطة واحدة بالضبط، وهي مخزن قوالب التصميم، الذي يخدم نسخةً محليةً حين يتعذّر بلوغ فهرسه الأعلى.
وبعض النقاط تعيد كل شيء في صفحة واحدة بحكم التصميم: أجهزة NAS، وحصص المشترك
المنفصلة، والأدوار، ونقاط الويبهوك. وتلك إما تحذف meta كليًّا أو تعلن
page_size مساويًا لـtotal وhas_next تساوي false. فلا تكتب حلقة ترقيم على
نقطة بلا meta.
سقف العمق، ولماذا يصمت الترقيم العميق
هذه هي المزلقة التي تستحق قراءتين.
الترقيم قائم على الإزاحة، وPostgres يجيب OFFSET n بإنتاج n صفًّا ثم رميها.
فطلب page=2000000000 هو مسح تسلسلي كامل لجدول المستأجر، يحتلّ اتصالًا ومخزن
الصفحات المشترك دقائق. ويستطيع عميل واحد فعل ذلك في حلقة.
لذلك تُقصّ الإزاحة عند 1,000,000 صف، وأي page بعد السقف يُقصّ، لا
يُرفض. فلا 400، ولا حقل تحذير، ولا details.reason. طلبت الصفحة 40,000
بحجم 50، فاستلمت الصفحة 20,000، والرد يبدو طبيعيًا تمامًا.
وكتلة meta هي حيث يظهر ذلك: فـmeta.page يعيد القيمة المقصوصة. أي:
المطلوب page=40000, page_size=50 → meta.page = 20000
فإن لم تكن meta.page هي الصفحة التي طلبتها فقد بلغت السقف. وتلك هي الإشارة
الوحيدة، والبرنامج الذي لا يقرأ meta.page أبدًا سيعيد جلب الصفحة نفسها إلى
الأبد بينما عدّاده يتصاعد.
والقصّ يتناسب مع حجم صفحتك، لأن الحدّ معبَّر عنه بالصفوف لا بالصفحات: فعند
page_size=50 أعمق صفحة يمكن بلوغها هي 20,000، وعند page_size=200 هي 5,000.
وذيل القائمة يبقى في المتناول بقلب order. فإن احتجت فعلًا الطرف البعيد
لمجموعة تتجاوز المليون صف، فرتّب بالاتجاه الآخر واقرأ من الطرف الآخر. وإن احتجت
المجموعة كلها فلا ترقّمها أصلًا — استعمل
مهمة تصدير، فهي تتدفق من جهة الخادم بلا
حساب إزاحة.
متى لا ترقّم
الترقيم لعرض شاشة صفوف على إنسان. أما استخراج جدول كامل فـPOST /api/v1/exports
يصفّ مهمةً غير متزامنة تتدفق بالصفوف إلى ملف CSV أو XLSX وتبلّغ عن تقدّمها،
وGET /api/v1/exports/{id}/download يجلب الناتج حين يجهز. وهي تحترم نطاق
الصلاحية نفسه الذي تحترمه قائمتك، ولا تمسّ سقف الإزاحة أبدًا.
وحلقة ترقيم على مئات الآلاف من الصفوف ستكون أبطأ، وستصطدم بحدّ المعدل، وستبلغ السقف. ومسار التصدير موجود بالضبط كي لا تضطر إلى كتابة واحدة.
آخر تحديث