هذه ترجمة للصفحة الأصلية بالإنجليزية. عند وجود أي اختلاف، تُعتمد النسخة الإنجليزية.
مواصفة OpenAPI في DaloyJS
يُصدر DaloyJS مستند OpenAPI 3.1 نظيفًا مباشرةً من تعريفات مساراتك، دون إضافات ودون مُزخرِفات (decorators) منفصلة. يتشارك التحقق والأنواع والمواصفة مصدرًا واحدًا للحقيقة.
سطر واحد: تركيب /docs و/openapi.json و/openapi.yaml تلقائيًا
على طريقة FastAPI. مرّر docs: "auto" (أو docs: true) إلى منشئ App، فيسجّل DaloyJS لك GET /openapi.json + GET /openapi.yaml (المواصفة الحية بالصيغتين) وGET /docs (واجهة مرجع API مع Scalar).
لا يركّب docs: "auto" المسارات إلا عندما لا يكون التطبيق في الإنتاج (وهذا هو الافتراضي في قوالب create-daloy، فلا تنشر الواجهة البرمجية المنشورة مخططها)، أو اتركه معطلًا (الافتراضي) وركّب المسارات يدويًا بالدوال المساعدة أدناه. خصّص المسارات والواجهة والوسوم عبر صيغة الكائن. ومنذ 1.5.5 تتصرف صيغة الكائن مثل "auto" ما لم تضبط enabled، لذا فإن تخصيص الواجهة لا ينشر خريطة مساراتك في الإنتاج عن طريق الخطأ أبدًا؛ اضبط enabled: true (أو docs: true) لواجهة برمجية عامة ينبغي أن تقدّم توثيقها في الإنتاج:
الأمان: المواصفة المنشورة خريطة كاملة لسطح الهجوم لديك: كل مسار ومعامل ومخطط مصادقة وشكل خطأ. معdocs: trueأوenabled: trueفي الإنتاج، يسجّل DaloyJS الحدثdocs.public_in_productionويقدّم المواصفة لكل من يستطيع الوصول إليها. هذا صحيح لواجهة برمجية عامة. أما لغير ذلك، فأبقِ"auto"، أو ضع التوثيق خلف مصادقة (فـbearerAuth()على مستوى التطبيق دونexcept()لـ/docsو/openapi.jsonيغطيهما). علّم مسارات الإدارة والمهام المجدولة وتصحيح الأخطاء بـinternal: true، فتُستبعد حينها من المستند المولَّد وتجيب بـ404على حركة الشبكة، بينما يظل بإمكانapp.inject()استدعاؤها. راجع Secure admin panels (بالإنجليزية).
اختر واجهة: Scalar أو Swagger UI أو Redoc
اضبط ui على "scalar" (الافتراضي) أو "swagger" أو "redoc". تعرض الثلاث المواصفة الحية نفسها، وتُركَّب على المسارات نفسها، وتأتي بسياسة CSP الصارمة نفسها وبموارد مستضافة على CDN، لذا فالتبديل تغيير بكلمة واحدة. يتضمن Scalar وSwagger UI وحدة طلبات للمطورين للمسارات المحمية. أما Redoc فواجهة مرجعية للقراءة فقط: تعرض متطلبات الأمان، لكنها لا تأتي بوحدة Try it مدمجة.
يحتفظ Swagger UI افتراضيًا بالتفويضات المدخلة في نافذة Authorize عبر إعادة التحميل. ويفعل ذلك بتخزين الرمز الملصق في localStorage الخاص بالمتصفح، وكذلك يفعل Scalar مع persistAuth: true. يمكن لأي سكربت يعمل على أصل التوثيق قراءته، ويبقى حتى بعد إغلاق التبويب. الصق رموز اختبار قصيرة العمر وبأقل صلاحيات فقط، ولا تلصق أبدًا بيانات اعتماد الإنتاج أو الإدارة، وقدّم التوثيق من أصل منفصل عن أي تطبيق ويب خاص بك. مرّر swagger: { persistAuthorization: false } لإبقاء الرموز في الذاكرة فقط. يختار Scalar تلقائيًا أول مخطط أمان مُعرَّف في OpenAPI، فيكون نموذج المصادقة جاهزًا ليلصق المطورون رمز bearer أو مفتاح API. إن أردت افتراضيًا مختلفًا في Scalar، فاضبطه صراحةً:
إذا احتاج توثيقك إلى نقطة دخول ظاهرة لتسجيل الدخول، فأضف docs.auth. يُعرض الزر نفسه في Scalar وSwagger UI وRedoc. وجّهه إلى نموذج تسجيل دخول محلي، أو مسار Better Auth، أو عنوان تسجيل دخول Clerk، أو عنوان تفويض OIDC من Auth0 أو Okta أو Microsoft Entra ID أو Cognito أو Keycloak أو أي مزوّد آخر:
يُمرَّر الكائن redoc كما هو إلى Redoc.init(specUrl, configuration, element). ولأن Redoc يبني فهرس البحث في Web Worker من نوع blob:، فإن المسار /docs المركّب تلقائيًا يوسّع سياسة CSP لتلك الصفحة بـ worker-src 'self' blob: في حالة ui: "redoc" فقط. ويحتفظ Scalar وSwagger UI بالسياسة الأضيق. ويُتجاهل الخيار scalar ما لم يكن ui هو "scalar"، وكذلك الحال مع swagger وredoc.
يُمرَّر الكائن scalar إلى واجهة HTML الخاصة بـ Scalar كإعدادات JSON، بينما يُبقي Daloy المسار الحي openapiPath مصدرًا. استخدمه للسمات، وCSS المخصص، والتخطيط، وافتراضيات المصادقة، وظهور العملاء، دون نسخ HTML الخاص بالتوثيق.
متقدم: توليد المواصفة يدويًا
تحتاج إلى كائن المواصفة الخام (لتوليد الشيفرة، أو اختبارات العقود، أو مسار مخصص)؟ استدعِ generateOpenAPI(app, options) مباشرةً:
متقدم: تقديم التوثيق من مسارك الخاص
مسار التوثيق المكتوب يدويًا مسار عادي، لذا لا ينطبق عليه تقييد docs: "auto". قرّر بنفسك هل ينبغي أن يوجد في الإنتاج وهل يحتاج إلى مصادقة. وينطبق الأمر نفسه على أي مسار /openapi.json تقدّمه يدويًا باستخدام generateOpenAPI():
تعيد كل من swaggerUiHtml وscalarHtml وredocHtml صفحات HTML مكتفية ذاتيًا تحمّل مواردها من jsDelivr مع سياسة CSP صارمة لا تسمح إلا بذلك الأصل. عندما تكتب المسار يدويًا باستخدام redocHtml، مرّر allowBlobWorkers: true إلى htmlResponse (أو docsContentSecurityPolicy) حتى تسمح سياسة CSP بعامل البحث blob: الخاص بـ Redoc:
إن أردت اختبار تجربة التوثيق مقابل عقد أكبر بكثير، فراجع عرض REST الوهمي الكبير (بالإنجليزية). فهو مقياس أفضل من مثال CRUD بسيط عندما تحتاج إلى التحقق من البحث والتجميع وأداء العرض.
الحفظ على القرص لتوليد الشيفرة
ما الذي يُصدَر
operationIdواحد لكل مسار، والمكررات ترمي خطأً عند التسجيل.- تُوحَّد معاملات المسار
:idإلى{id}. - تُحوَّل أجسام المخططات عبر
schema.toJSONSchema?.()عندما يكون مدعومًا، أو عبر بديل هيكلي. - مكوّن قابل لإعادة الاستخدام
components.schemas.Problemلأخطاء RFC 9457. tagsوsummaryوdescription، وdescriptionلكل رمز حالة.- تُحذف المسارات المعلّمة بـ
internal: trueما لم تمرّرincludeInternal: true(مثلًا لعقد داخلي فقط لأدواتك الخاصة). لا تنشر ذلك المستند أبدًا.
Webhooks
يسمح OpenAPI 3.1 للمنتِج بنشر webhooks في المستوى الأعلى، وهي عمليات يُتوقع من المستهلك تنفيذها. مرّر webhooks إلى generateOpenAPI فيُصدرها DaloyJS تحت الخريطة webhooks في المستوى الأعلى من المستند.
الخريطة webhooks تصف العملية فقط؛ فهي لا تسلّم شيئًا ولا تؤمّنه. في عمليات التسليم الحقيقية، وقّع كل حمولة حتى يتمكن المستقبلون من التحقق من المصدر والسلامة معًا، وأضف طابعًا زمنيًا حتى يتمكنوا من رفض إعادة الإرسال. ورمز bearer ثابت وحده لا يثبت أيًا منهما. يوقّع createWebhookSender() (بالإنجليزية) كل طلب صادر ويضيف إليه طابعًا زمنيًا ويعيد محاولته ويمرره عبر fetchGuard(). ويتحقق المستقبلون باستخدام verifyWebhookSignature(). وثّق ترويسات التوقيع في description الخاص بالـ webhook.
الاستدعاءات الراجعة
تصف الاستدعاءات الراجعة (callbacks) طلبات خارج النطاق قد تُطلقها عملية ما نحو المستهلك (مثل نقطة نهاية اشتراك ترسل لاحقًا طلب POST إلى العنوان الذي قدّمه المستدعي). أرفق خريطة callbacks مباشرةً بمسار أو webhook.
الأمان: عنوان الاستدعاء الراجع الذي يقدّمه المستدعي نقطة تصريف لتزوير الطلبات من جهة الخادم (SSRF). التحقق من المخطط لا يكفي. فـz.url()وحده يقبلhttp://169.254.169.254/(بيانات السحابة الوصفية)، وhttp://localhost:6379/، وعناوينfile:/gopher:، وحتىz.url({ protocol: /^https$/ })يظل يقبلhttps://169.254.169.254/أو اسم مضيف يُحل إلى عنوان خاص. أرسل كل استدعاء راجع عبرsafeFetchمنfetchGuard()(بالإنجليزية)، الذي يفحص العنوان المحلول وكل قفزة إعادة توجيه. والأفضل من ذلك، سلّم باستخدامcreateWebhookSender()(بالإنجليزية)، الذي يوقّع الحمولة أيضًا. وفكّر في التحقق من ملكية العنوان، مثلًا بطلب تحدٍّ، قبل تخزينه.
يرتبط كل اسم استدعاء راجع بمفتاح تعبير وقت تشغيل واحد أو أكثر (مثل "{$request.body#/callbackUrl}")، ويرتبط كل منها بعملية واحدة أو أكثر مفهرسة بطريقة HTTP. وتُتخطى الخرائط والمصفوفات الفارغة، فتمرير استدعاء راجع فارغ لا ينتج أبدًا مواصفة مشوّهة.
الاتحادات المميَّزة
الحقل discriminator في OpenAPI 3.1 هو الطريقة المعتمدة لوصف الاتحادات الموسومة. يوفّر DaloyJS دالتين مساعدتين من @daloyjs/core/openapi (ومن الحزمة الجذرية):
discriminator(propertyName, mapping?): باني المواصفة المجرد. استخدمه عندما يكون لديك JSON Schema مكتوب يدويًا وتريد إرفاق الحقل بشكل نظيف.discriminatedUnion(propertyName, variants, opts?): غلاف متوافق مع Standard Schema يتحقق في وقت التشغيل (موزّعًا حسب قيمة المميِّز) ويعرض أيضًا.toJSONSchema()حتى يُصدر مولّد OpenAPI البنية{ oneOf, discriminator }تلقائيًا.
في وقت التشغيل، يرفض الغلاف غير الكائنات، والمميِّزات المفقودة أو غير النصية، وقيم المميِّز غير المعروفة (بما فيها الأسماء الموروثة مثل __proto__ وconstructor وtoString) مع مشكلة Standard Schema واضحة، ثم يُحيل كل ما عدا ذلك إلى أداة التحقق الخاصة بالمتغير المطابق.
آخر تحديث: