استراتيجيات عملية لتحديد معدل الاستخدام في واجهات برمجة تطبيقات GraphQL
January 4, 2024
تنفيذ تحديد معدل الوصول على واجهات برمجة التطبيقات (REST APIs) يعتبر أمرًا بسيطًا نسبيًا، حيث نستخدم عادة مسارات URI لتمثيل موارد واجهات برمجة التطبيقات المحددة وطرق HTTP للإشارة إلى العمليات على الموارد. يمكن للطبقة الوكيلة بسهولة فرض قواعد تحديد المعدل المحددة مسبقًا بناءً على هذه المعلومات.
ومع ذلك، يصبح السيناريو أكثر تعقيدًا بشكل كبير عندما يتعلق الأمر بواجهات برمجة التطبيقات GraphQL. دعونا نتعمق في كيفية التغلب على هذه التحديات.
السيناريوهات البسيطة
على عكس واجهات برمجة التطبيقات REST، تستخدم GraphQL لغة استعلام خاصة بها. لم تعد تعتمد على المسارات وطرق HTTP لاسترداد الموارد ومعالجتها، بل توحد استعلام البيانات والعمليات تحت Query و Mutation، حيث يقوم Query باسترداد البيانات، وتقوم Mutation بإجراء عمليات معالجة البيانات مثل الإنشاء والتحديث والحذف.
GET /users
GET /users/1
POST /users
PUT /users/1
DELETE /users/1
query { users { fullName } }
query { user(id: 1) { fullName } }
mutation { createUser(user: { lastName: "Jack" }) { id, fullName } }
mutation { updateUser (id: 1, update: { lastName: "Marry" }) { fullName } }
mutation { deleteUser (id: 1) }
توضح الأمثلة أعلاه التحول في طرق استعلام واجهات برمجة التطبيقات. على عكس REST، تشبه GraphQL استدعاء وظائف على الموارد، مع تمرير معلمات الإدخال الضرورية، حيث تحتوي الاستجابة على البيانات المستعلام عنها. بالإضافة إلى الاختلافات في طرق الاستعلام، تعرض GraphQL واجهات برمجة التطبيقات عادة من خلال نقطة نهاية واحدة (مثل /graphql)، مع إرسال الاستعلامات ومعلمات الإدخال عبر جسم POST.
فكر في المثال التالي:
query {
users {
fullName
}
photos {
url
uploadAt
}
}
في هذا السيناريو، يتم محاكاة الصفحة الرئيسية لألبوم، حيث يتم استدعاء واجهة برمجة التطبيقات إلى نقطة النهاية /graphql
لاستعلام قوائم المستخدمين والصور في نفس الوقت. الآن، فكر فيما إذا كانت استراتيجيات الخادم الوكيل العكسي التقليدية، التي يتم تنفيذها على مستوى الطلب، لا تزال قابلة للتطبيق على واجهات برمجة التطبيقات GraphQL.
الجواب هو لا. لا يمكن لخوادم الوكيل العكسي التقليدية التعامل بشكل فعال مع استدعاءات واجهات برمجة التطبيقات GraphQL التي تحتوي على الاستعلامات نفسها، مما يجعل من المستحيل فرض سياسات مثل تحديد المعدل. بالنسبة لواجهات برمجة التطبيقات GraphQL، تبدو دقة "طلبات HTTP" خشنة جدًا.
ومع ذلك، فإن بوابة واجهة برمجة التطبيقات، Apache APISIX، تتضمن دعمًا مدمجًا لقدرات GraphQL إلى HTTP. يمكن للمسؤولين تكوين عبارة استعلام مسبقًا، مما يسمح للعملاء باستدعائها مباشرة عبر HTTP POST دون فهم تفاصيل GraphQL، فقط بتوفير معلمات الإدخال الضرورية. هذا لا يعزز الأمان فحسب، بل يمكّن أيضًا من تطبيق سياسات واجهة برمجة التطبيقات HTTP في هذا السياق.
بشكل فعال، يحول هذا الاستعلامات الديناميكية لـ GraphQL إلى استعلامات ثابتة مدفوعة بالمعرفة مقدمة من مزودي واجهات برمجة التطبيقات، مما يعرض مزايا وعيوب. في بعض الأحيان، قد لا نرغب في التضحية بميزة الاستعلام الديناميكي لـ GraphQL. دعونا نواصل مناقشة السيناريوهات الأخرى.
السيناريوهات المعقدة
تستخدم GraphQL لغتها المتخصصة لنمذجة البيانات ووصف واجهات برمجة التطبيقات، مما يسمح ببنى بيانات متداخلة. بتوسيع المثال السابق:
query {
photos(first: 10) {
url
uploadAt
publisher {
fullName
avatar
}
comments(first: 10) {
content
sender {
fullName
avatar
}
}
}
// users...
}
في هذه الحالة، يتم محاكاة استرداد أول 10 صور، بما في ذلك الناشر لكل صورة وأول 10 تعليقات مع مرسليها، يجب على خدمة الخلفية التعامل مع استعلامات تتضمن جداول بيانات متعددة أو استدعاءات لخدمات صغيرة. في سيناريوهات الاستعلام المتداخلة هذه، مع زيادة كمية البيانات ومستويات التداخل، يرتفع الضغط الحسابي على خدمات الخلفية وقواعد البيانات بشكل كبير.
لمنع الاستعلامات المعقدة من إرهاق الخدمة، قد نرغب في فحص وحظر مثل هذه الاستعلامات في طبقة الوكيل. لتطبيق هذه الاستراتيجية، يجب على مكون الوكيل تحليل عبارات الاستعلام إلى بيانات منظمة، واجتيازها للحصول على الحقول المتداخلة في كل طبقة، واتباع الممارسة الشائعة لـ GraphQL بتعيين قيم تعقيد للحقول كتكاليف استعلام. يمكن بعد ذلك فرض حدود عالمية على إجمالي تعقيد الاستعلام. بالنسبة للاستعلام أعلاه، بافتراض تكلفة 1 لكل حقل فردي:
10 * photo (url + uploadAt + publisher.fullName + publisher.avatar + 10 * comment (content + sender.fullName + sender.avatar))
10 * (1 + 1 + 1 + 1 + 10 * (1 + 1 + 1)) = 340
مع إجمالي تكلفة استعلام تبلغ 340، يبدو ذلك مقبولًا، ويمكننا تكوين حدود تكلفة استعلام واجهة برمجة التطبيقات بناءً على مثل هذه القواعد. ومع ذلك، إذا حاول عميل ضار جلب بيانات 100 صورة في استعلام واحد، فإن تكلفة الاستعلام ستصل إلى 3400، مما يتجاوز الحد المحدد مسبقًا، ويؤدي إلى رفض الطلب.
بالإضافة إلى تقييد الحد الأقصى للتكلفة لكل استعلام عميل، يمكن فرض حدود إضافية على فترات زمنية، مثل السماح للعملاء بإجمالي 2000 استعلام في الدقيقة ورفض الاستعلامات الزائدة، مما يمكن أن يعيق المتسللين الضارين.
لتنفيذ مثل هذه القدرات، يجب على مكون الوكيل تحليل وحساب تكاليف الاستعلام. يدعم API7 Enterprise هذه الميزات، مما يمكّن من التحليل الديناميكي لاستعلامات GraphQL وتنفيذ حدود المعدل للمستخدمين بناءً على التكوينات.
تواجه واجهات برمجة التطبيقات GraphQL تحديات في طبقة الوكيل، حيث تواجه الخوادم الوكيلة التقليدية صعوبة في إدراك ومعالجة التعقيد وعلاقات التداخل داخل عبارات استعلام GraphQL. في المقابل، تثبت تقنيات بوابة واجهة برمجة التطبيقات قيمتها في التغلب على هذه التحديات حيث يمكن أن يكون API7 Enterprise خيارًا رائعًا.