ربما سمعت عن جيثب كلي و كل الأشياء الرائعة يمكنك القيام به. ومع ذلك ، فإن أحد القوى العظمى المخفية هو القدرة على تنفيذ الاستعلامات والطفرات المعقدة من خلال واجهة برمجة تطبيقات Github’s GraphQL. سوف يسير هذا المنشور من خلال نقطة نهاية Github’s GraphQL API وكيفية الاستعلام عنها مع Github CLI.

ما هو GraphQL؟

لنبدأ بالأساسيات: GraphQl هي لغة استعلام لبرنامج واجهات برمجة التطبيقات ووقت التشغيل لتنفيذ تلك الاستعلامات ضد بياناتك. على عكس واجهات برمجة تطبيقات REST التقليدية التي توفر هياكل بيانات ثابتة من نقاط النهاية المحددة مسبقًا ، يتيح GraphQL للعملاء طلب البيانات التي يحتاجونها بالضبط في طلب واحد. يقلل نهج المسابقة الفردية هذا الشبكة ، ويسرع أداء التطبيق ، ويؤدي إلى تبسيط المنطق من جانب العميل من خلال التخلص من الحاجة إلى التوفيق مفتوح من مصادر في عام 2015.

تأتي عمليات GraphQL في نوعين أساسيين: الاستعلامات والطفرات. استفسارات هي عمليات القراءة فقط التي تسترجع البيانات دون إجراء أي تغييرات-على غرار الحصول على الطلبات في راحة. طفرات، من ناحية أخرى ، يتم استخدامها لتعديل البيانات من جانب الخادم (إنشاء أو تحديث أو حذف)-قابلة للنشر ، تصحيح ، وضع ، وحذف في واجهات برمجة التطبيقات REST. هذا الفصل الواضح بين عمليات القراءة والكتابة يجعل تفاعلات GraphQL يمكن التنبؤ بها مع الحفاظ على المرونة لتحديد البيانات التي يجب إرجاعها بدقة بعد إجراء التغيير.

كيف يتم استخدام GraphQL في Github؟

جيروب تم تنفيذ GraphQL في عام 2016 لمعالجة قيود واجهات برمجة التطبيقات المريحة. عزز هذا التبني تجربة المطور بشكل كبير عند العمل مع بيانات GitHub. مع نقطة نهاية GraphQL ، يمكنك استرداد مشكلات المستودع ، وعلاماته ، والمخصصين ، والتعليقات مع استعلام GraphQL واحد. باستخدام واجهات برمجة تطبيقات REST الخاصة بنا ، كان هذا سيتخذ عدة مجموعات من المكالمات المتداخلة.

لا يمكن الوصول إلى بعض بيانات وعمليات Github إلا من خلال واجهة برمجة تطبيقات GraphQL (مثل المناقشات والمشاريع وبعض إعدادات المؤسسات) ، والبعض الآخر حصريًا من خلال واجهات برمجة تطبيقات REST (مثل إجراءات سير العمل ، والمتسابقين ، أو السجلات) ، وبعضها يستخدم أي من نقطة النهاية (مثل المستودعات ، والمشكلات ، وطلبات السحب ، ومعلومات المستخدم). يمكن الوصول إلى نقطة نهاية Github GraphQL في api.github.com/graphql ويمكنك استكشاف المخطط الكامل في توثيق GraphQL أو من خلال التفاعلية GraphQl Explorer.

إن الاعتبار الرئيسي عند الاختيار بين API REST و API GraphQL هو كيفية حساب حدود المعدل. كملخص سريع لكيفية تنفيذ ذلك:

  • استراحة API: محدودة بعدد الطلبات (عادة 5000 طلب في الساعة للمستخدمين المصادقين وما يصل إلى 15000 لتطبيقات GitHub المثبتة في مؤسسة)
  • GraphQL API: محدودة بـ “النقاط” (عادةً 5000 نقطة في الساعة للمستخدمين المصادقين ولكن يمكن أن تصل إلى 10،000-12500 نقطة في الساعة لتطبيقات GitHub)

يكلف كل استعلام GraphQL نقطة واحدة على الأقل ، ولكن تزداد التكلفة بناءً على تعقيد استعلامك (عدد العقد المطلوبة ، والاتصالات التي تم اجتيازها ، وما إلى ذلك). يوفر API GraphQL A rateLimit الحقل يمكنك تضمينه في استفساراتك للتحقق من حالة الحد الحالي.

بالنسبة للسيناريوهات التي تحتاج فيها إلى إحضار البيانات ذات الصلة التي تتطلب خلافًا لمكالمات REST متعددة ، غالبًا ما يكون GraphQL أكثر ودية للمعدل لأن:

  • قد يكلف استعلام GraphQL المعقد 5-10 نقطة ولكن استبدل مكالمات API منفصلة من 5 إلى 10.
  • أنت تتجنب بيانات “الإفراط في الإحصار” التي لا تحتاجها ، والتي تساعد بشكل غير مباشر في حدود الأسعار.
  • يسمح API GraphQL باختيار المزيد من الحقول الحبيبية ، مما قد يقلل من التعقيد وتكلفة النقطة.

ومع ذلك ، يمكن أن تستخدم استعلامات GraphQL المحسّنة بشكل سيئ التي تطلب كميات كبيرة من البيانات المتداخلة الحد الأقصى للمعدل بشكل أسرع من طلبات الراحة المكافئة – وتجري بسرعة حد السعر الثانوي مشاكل.

قاعدة سريعة من الإبهام على اتخاذ القرار الذي يجب استخدامه:

  • للاستعلام عن الكائنات العلائقية ، مثل مشاريع GitHub وقضاياها ، غالبًا ما يكون GraphQL أكثر فاعلية ، خاصة إذا كان عددًا منفصلًا من العناصر.
  • بالنسبة للبيانات السائبة من نوع واحد أو نقاط بيانات واحدة ، مثل سحب قائمة أسماء المستودعات في المؤسسة ، غالبًا ما يفضل واجهة برمجة تطبيقات REST.

في بعض الأحيان لا توجد إجابة صحيحة أو خاطئة ؛ طالما وجود الكائن ، جرب واحد!

لماذا تستخدم github cli لـ GraphQL؟

بينما يبدأ العديد من المطورين بـ Github’s GraphQl Explorer على الويب ، curl، أو أدوات الاستعلام عن واجهة برمجة التطبيقات الأخرى ، هناك نهج أكثر تبسيطًا: استخدام دعم GraphQL المدمج في Github CLI. قبل الغوص في الإرشاد ، دعونا نفهم لماذا غالبًا ما يكون github cli أداة الانتقال الخاصة بي لاستعلامات وطفرات GraphQL:

  1. تتم معالجة المصادقة تلقائيًا: لا حاجة لإدارة رموز الوصول الشخصية يدويًا.
  2. بناء جملة مبسط: أبسط من الصياغة curl الأوامر.
  3. التنمية المحلية الصديقة: تشغيل الاستعلامات والطفرات مباشرة من المحطة الخاصة بك.
  4. معالجة JSON: خيارات مدمجة لتصفية وتنسيق نتائج.
  5. دعم ترقيم الصفحات: القدرة على العمل مع ترقيم الصفحات المستندة إلى المؤشر في استجابات GraphQL.
  6. تجربة متسقة: نفس الأداة التي من المحتمل أن تستخدمها لمهام GitHub الأخرى.

كيف تبدأ مع gh api graphql

أولا ، تأكد من أن لديك GitHub CLI مثبت و مصادقة مع gh auth login. بناء الجملة الأساسي لعمل استعلام GraphQL مع gh api graphql يكون:

gh api graphql -H X-Github-Next-Global-ID:1 -f query='
  query {
    viewer {
      login
      name
      bio
    }
  }
'

يعيد هذا الاستعلام البسيط اسم مستخدم Github الخاص بك ، والاسم الذي حددته في ملفك الشخصي ، وسيرتك الذاتية. ال -f العلم يحدد متغيرات النماذج ، مع query= كونه استعلام GraphQL نفسه.

هذا هو مثالنا الإخراج:

{
  "data": {
    "viewer": {
      "login": "joshjohanning",
      "name": "Josh Johanning",
      "bio": "DevOps Architect | GitHub"
    }
  }
}

تشغيل الاستفسارات والطفرات

مثال الاستعلام الأساسي

دعونا نجرب شيئًا أكثر عملية – تقديم معلومات حول مستودع ما. للبدء ، سنستخدم الاستعلام التالي:

gh api graphql -H X-Github-Next-Global-ID:1 -f query='
  query($owner:String!, $repo:String!) {
    repository(owner:$owner, name:$repo) {
      name
      description
      id
      stargazerCount
      forkCount
      issues(states:OPEN) {
        totalCount
      }
    }
  }
' -F owner=octocat -F repo=Hello-World

ال -F يقوم العلم بتعيين القيم المتغيرة التي يتم الرجوع إليها في الاستعلام مع $variable.

هذا هو مثالنا الإخراج:

{
  "data": {
    "repository": {
      "name": "Hello-World",
      "description": "My first repository on GitHub!",
      "id": "R_kgDOABPHjQ",
      "stargazerCount": 2894,
      "forkCount": 2843,
      "issues": {
        "totalCount": 1055
      }
    }
  }
}

💡 نصيحة: ال -H X-Github-Next-Global-ID:1 المعلمة تعيين رأس HTTP يوجه واجهة برمجة تطبيقات Github لاستخدام تنسيق معرف العقدة العالمي الجديد بدلا من التنسيق القديم. على الرغم من أن استعلامك سيعمل بدون هذا الرأس ، بما في ذلك أنه يمنع تحذيرات الإهمال عند الرجوع إلى معرفات العقدة (مثل الممر repository.ID في العمليات اللاحقة). يوصي Github بتبني هذا التنسيق لجميع عمليات التكامل الجديدة لضمان التوافق طويل الأجل.

تشغيل الطفرات

طفرات تعمل بالمثل. إليك كيفية إنشاء مشكلة جديدة:

gh api graphql -H X-Github-Next-Global-ID:1 -f query='
  mutation($repositoryId:ID!, $title:String!, $body:String) {
    createIssue(input:{repositoryId:$repositoryId, title:$title, body:$body}) {
      issue {
        url
        number
        title
        body
        state
      }
    }
  }
' -F repositoryId="R_kgDOABPHjQ" -F title="Creating issue with GraphQL" -F body="Issue body created via GraphQL\!"

تأكد من تحديث repositoryId المعلمة مع معرف GraphQL الخاص بالمستودع الفعلي (مثال على إرجاع معرف المستودع يظهر في الاستعلام الأساسي أعلاه!).

هذا هو مثالنا الإخراج:

{
  "data": {
    "createIssue": {
      "issue": {
        "url": "https://github.com/octocat/Hello-World/issues/3706",
        "number": 3706,
        "title": "Creating issue with GraphQL",
        "body": "Issue body created via GraphQL!",
        "state": "OPEN"
      }
    }
  }
}

تصفية نتائج GraphQL

جيثب CLI يدعم JQ-تصفية طراز لاستخراج أجزاء محددة من الاستجابة ، والتي لا تقدر بثمن عندما تحتاج إلى تحليل أسماء المستودعات أو عناوين URL فقط من استعلام للاستخدام في البرامج النصية الأتمتة. هنا مثال على استخدام --jq علَم:

gh api graphql -H X-Github-Next-Global-ID:1 -f query='
  query($owner:String!, $repo:String!) {
    repository(owner:$owner, name:$repo) {
      issues(first:3, states:OPEN) {
        nodes {
          number
          title
          url
        }
      }
    }
  }
' -F owner=octocat -F repo=Hello-World --jq '.data.repository.issues.nodes()'

ال --jq يقبل Flag تعبيرات JQ لمعالجة إخراج JSON. يعيد هذا الاستعلام مجموعة من المشكلات ، دون بنية استجابة GraphQL المحيطة.

هذا هو مثالنا الإخراج:

{
  "number": 26,
  "title": "test issue",
  "url": "https://github.com/octocat/Hello-World/issues/26"
}
{
  "number": 27,
  "title": "just for test",
  "url": "https://github.com/octocat/Hello-World/issues/27"
}
{
  "number": 28,
  "title": "Test",
  "url": "https://github.com/octocat/Hello-World/issues/28"
}

يمكن أن نقوم بتعديل --jq العلم فقط لإرجاع عناوين URL ، مثل ذلك:

gh api graphql -H X-Github-Next-Global-ID:1 -f query='
  query($owner:String!, $repo:String!) {
    repository(owner:$owner, name:$repo) {
      issues(first:3, states:OPEN) {
        nodes {
          number
          title
          url
        }
      }
    }
  }
' -F owner=octocat -F repo=Hello-World --jq '.data.repository.issues.nodes().url'

هذا هو مثالنا الإخراج:

https://github.com/octocat/Hello-World/issues/26
https://github.com/octocat/Hello-World/issues/27
https://github.com/octocat/Hello-World/issues/28

التعامل مع ترقيم الصفحات

يحد Github’s GraphQL API النتائج بحد أقصى 100 عنصر لكل صفحة، مما يعني أنك ستحتاج إلى ترقيم الصفحات لاسترداد مجموعات بيانات أكبر.

يعمل ترقيم الصفحات في GraphQL عن طريق إرجاع “المؤشر” مع كل صفحة من النتائج ، والتي تعمل كمؤشر إلى المكان الذي يجب أن تبدأ فيه المجموعة التالية من النتائج. عندما تطلب الصفحة التالية ، يمكنك تقديم هذا المؤشر للإشارة إلى مكان البدء.

أسهل طريقة للتعامل مع هذا الترقيم في github cli هي مع --paginate Flag ، الذي يجمع تلقائيًا جميع صفحات النتائج لك من خلال إدارة هذه المؤشرات وراء الكواليس. إليك ما يبدو في الاستعلام:

gh api graphql --paginate -H X-Github-Next-Global-ID:1 -f query='
  query($owner:String!, $repo:String!, $endCursor:String) {
    repository(owner:$owner, name:$repo) {
      issues(first:100, after:$endCursor, states:OPEN, orderBy:{field:CREATED_AT, direction:DESC}) {
        pageInfo {
          hasNextPage
          endCursor
        }
        nodes {
          number
          title
          createdAt
        }
      }
    }
  }
' -F owner=octocat -F repo=Hello-World

كائن pageinfo مع hasNextPage و endCursor الحقول ضرورية لترقيم الصفحات. عندما تستخدم --paginate Flag ، يستخدم GitHub CLI هذه الحقول تلقائيًا لجلب جميع الصفحات المتاحة لاستعلامك ، مع الجمع بين النتائج في استجابة واحدة.

هذا هو مثالنا الإخراج:

{
  "data": {
    "repository": {
      "issues": {
        "pageInfo": {
          "hasNextPage": true,
          "endCursor": "Y3Vyc29yOnYyOpK5MjAyNC0xMi0zMFQxNDo0ODo0NC0wNjowMM6kunD3"
        },
        "nodes": (
          {
            "number": 3708,
            "title": "Creating issue with GraphQL once more",
            "createdAt": "2025-04-02T18:15:11Z",
            "author": {
              "login": "joshjohanning"
            }
          },
          {
            "number": 3707,
            "title": "Creating issue with GraphQL again",
            "createdAt": "2025-04-02T18:15:02Z",
            "author": {
              "login": "joshjohanning"
            }
          },
          {
            "number": 3706,
            "title": "Creating issue with GraphQL",
            "createdAt": "2025-04-02T18:14:37Z",
            "author": {
              "login": "joshjohanning"
            }
          },
          … and so on
        )
      }
    }
  }
}

يعمل هذا النهج بشكل رائع بالنسبة لكميات معتدلة من البيانات ، ولكن ضع في اعتبارك أن Github’s GraphQL API حدود معدل، قد تحتاج الاستفسارات الكبيرة للغاية إلى تنفيذ التأخير بين الطلبات.

💡 قيود مهمة: ال --paginate يمكن للعلم أن يتعامل فقط مع ترقيم الصفحات لاتصال واحد في وقت واحد. على سبيل المثال ، عند إدراج مشكلات مستودع المستودع كما هو موضح أعلاه ، يمكن أن يتجول في جميع القضايا ، ولكن لا يمكن أن يتراكم في وقت واحد من خلال تعليقات كل قضية. لترقيم الصفحات المتداخلة ، ستحتاج إلى تنفيذ منطق مخصص.

بناء البرامج النصية المعقدة: استفسارات GraphQL معًا

عند العمل مع واجهة برمجة تطبيقات Github’s GraphQL ، فغالبًا ما تحتاج إلى توصيل استفسارات متعددة لإنجاز مهمة معقدة. دعونا نلقي نظرة على كيفية سلسلة مكالمات GraphQL معًا باستخدام Github CLI:

ISSUE_ID=$(gh api graphql -H X-Github-Next-Global-ID:1 -f query='
  query($owner: String!, $repo: String!, $issue_number: Int!) {
    repository(owner: $owner, name: $repo) {
      issue(number: $issue_number) {
        id
      }
    }
  }
' -F owner=joshjohanning -F repo=graphql-fun -F issue_number=1 --jq '.data.repository.issue.id') 
gh api graphql -H GraphQL-Features:sub_issues -H X-Github-Next-Global-ID:1 -f query='
query($issueId: ID!) {
  node(id: $issueId) {
    ... on Issue {
      subIssuesSummary {
        total
        completed
        percentCompleted
      }
    }
  }
}' -F issueId="$ISSUE_ID"

إليك ما يفعله هذا البرنامج النصي القذيف:

  1. يلتقط الاستعلام الأول معرف القضية باستخدام اسم المستودع ورقم الإصدار
  2. ال --jq يستخلص العلم فقط قيمة المعرف ويخزنها في متغير
  3. يمر الاستعلام الثاني هذا المعرف لاسترداد ملخص للقضايا الفرعية

هذا هو مثالنا الإخراج:

{
  "data": {
    "node": {
      "subIssuesSummary": {
        "total": 3,
        "completed": 1,
        "percentCompleted": 33
      }
    }
  }
}

خذ هذا معك

ال gh api graphql يوفر الأمر طريقة مريحة للتفاعل مع واجهة برمجة تطبيقات Github’s GraphQL مباشرة من المحطة الخاصة بك. إنه يلغي الحاجة إلى إدارة الرمز المميز ، ويبسيط بناء جملة الاستعلام والتنسيق ، ويتعامل مع ترجم الأساس الأساسي الذي سيكون معقدًا. سواء كنت تدير استعلامات معقدة أو طفرات بسيطة ، فإن هذا النهج يوفر تجربة مطور مبسطة.

في المرة القادمة التي تحتاج فيها إلى التفاعل مع API Github’s GraphQL ، تخطي مستكشف GraphQL على الويب وجرب نهج Github CLI. قد تصبح مجرد طريقتك المفضلة للعمل مع إمكانات GrapiQL القوية لـ Github.

كتبه

جوشوا يوهانينج

جوش هو مهندس ديفوبس كبير في فريق جيثب فاستتراك. لديه خبرة واسعة في الترويج لمبادئ DevOps للشركات الكبيرة والصغيرة من وقته كمستشار والآن في Github. إنه متحمس للغاية لتسريع رحلات الفرق السحابية مع إجراءات GitHub و Github. في وقته ، يتمتع جوش بمشاريع تحسين المنازل ، والسفر إلى أماكن جديدة ، وخلط الكوكتيلات الحرفية ، وقضاء الوقت مع زوجته وقططه وابنته.

Source link


اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *