نعم، من الممكن جدًا تحقيق ذلك باستخدام استدعاء واحد لـ GraphQL في GitLab API، وهذا هو أحد الأسباب الرئيسية لاستخدام GraphQL: القدرة على طلب بيانات متعددة ومترابطة في استعلام واحد فقط، بدلًا من إجراء عدة طلبات REST API منفصلة.
النهج الحالي الخاص بك يتضمن:
استدعاء repository/tree
للحصول على قائمة الملفات.
ثم استدعاء repository/commits
لكل ملف بشكل منفصل للحصول على آخر تحديث له. هذا هو ما يسبب مشكلة الكفاءة (مشكلة N+1).
يمكنك استخدام استعلام GraphQL لطلب معلومات عن الشجرة (repository tree) والالتزامات (commits) المرتبطة بها في نفس الطلب. ستحتاج إلى التركيز على كائنات TreeEntry
(لتمثيل الملفات والمجلدات في الشجرة) وكيفية الوصول إلى معلومات الالتزامات الخاصة بها.
إليك مثال على استعلام GraphQL يمكنك استخدامه (مع افتراض أن لديك الـ projectId
والـ ref
المناسبين):
GraphQL
query GetRepositoryTreeWithLastCommitInfo($projectPath: ID!, $ref: String!) {
project(fullPath: $projectPath) {
repository {
tree(ref: $ref) {
# يمكننا طلب عقد الشجرة مباشرة (الملفات والمجلدات)
nodes {
# يمكن أن يكون هذا ملفاً أو مجلدًا
name
path
type # FILE, TREE, BLOB, etc.
# إذا كان ملفاً، يمكننا طلب آخر التزام له
... on TreeEntry { # نستخدم фрагment للتركيز على TreeEntry (الملفات)
lastCommit {
# معلومات عن آخر التزام
id
sha
message
authoredDate # هذا هو الوقت الذي تم فيه التحديث الأخير
author {
name
email
}
}
}
}
}
}
}
}
المتغيرات (Variables) التي ستحتاجها لهذا الاستعلام:
JSON
{
"projectPath": "your-group/your-project-name", # مسار المشروع الكامل (مثلاً "my-group/my-project")
"ref": "main" # أو hash الالتزام الخاص بك (مثلاً "8af436d5abd261d32919d6525dbad617f7207bcc")
}
شرح الاستعلام:
project(fullPath: $projectPath)
: نحدد المشروع باستخدام المسار الكامل (أفضل من الـ ID في GraphQL عادةً).
repository { tree(ref: $ref) { ... } }
: نصل إلى الشجرة في المستودع بالـ ref
المحدد (سواء كان فرعًا أو هش التزام).
nodes { ... }
: نطلب جميع العناصر داخل الشجرة (ملفات ومجلدات).
name
و path
و type
: معلومات أساسية عن كل عنصر في الشجرة.
... on TreeEntry { lastCommit { ... } }
: هذا هو الجزء الأهم. نستخدم Inline Fragment لتحديد أننا نريد حقل lastCommit
فقط إذا كان الكائن الحالي هو TreeEntry
(أي ملف).
lastCommit { ... }
: داخل lastCommit
، يمكنك طلب تفاصيل مثل authoredDate
(وهو آخر وقت تحديث تريده غالبًا)، message
، author
، وغيرها.
الحصول على projectPath
: بدلاً من project_id
(66677391)، ستحتاج إلى المسار الكامل للمشروع (مثل my-org/my-project
). يمكنك الحصول عليه من واجهة GitLab على الويب أو من استدعاء API آخر إذا لزم الأمر.
استخدام نقطة نهاية GraphQL: بدلًا من repository/tree
أو repository/commits
، ستقوم بإرسال هذا الاستعلام إلى نقطة نهاية GraphQL العامة لـ GitLab، وهي عادةً: https://gitlab.com/api/graphql
المصادقة (Authentication): ستحتاج إلى تضمين الـ Private Token الخاص بك في رأس الطلب (Header)، عادةً كـ Authorization: Bearer <your_personal_access_token>
.
كفاءة عالية: تستدعي الـ API مرة واحدة فقط، مما يقلل من زمن الاستجابة ويقلل الحمل على السيرفر.
مرونة: يمكنك طلب البيانات التي تحتاجها بالضبط، لا أكثر ولا أقل.
سهولة التوسع: إذا احتجت المزيد من البيانات في المستقبل، يمكنك تعديل الاستعلام دون الحاجة إلى استدعاءات API إضافية.
جرب هذا الاستعلام في أداة اختبار GraphQL (مثل GraphiQL المدمجة في بعض منصات GitLab، أو Postman، أو أي عميل GraphQL). هل هذا يساعدك على فهم كيفية البدء؟