مخططات GraphQL كتابة، تنسيق، وفهم SDL دون الحاجة إلى الكود المكرر

تحديث في

تُعدّ مخططات GraphQL عقوداً ذات وصف مدمج بين الخادم والعميل. يُعرض هذا الدليل لك كيفية إنشاء لغة تعريف المخطط (SDL) من الصفر — أنواع، مُدخلات، استعلامات، تغييرات، أنواع المدخلات، أنواع محددة، وواجهات — بحيث يمكنك قراءة وكتابة المخططات بثقة.

مخططات GraphQL: كتابة، تنسيق، وفهم SDL دون الحاجة إلى الكود المكرر 1
إعلان · حذف؟

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

ما هو النموذج الحقيقي للـ GraphQL؟

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

تبدأ كل واجهة برمجة بـ نموذج مكتوب بلغة SDL. يُتحقق من جميع الاستعلامات ضد هذا النموذج أثناء التشغيل. إذا طلب العميل حقلًا لا يوجد في النموذج، يتم رفض الطلب قبل تنفيذ أي مُحلّل. وهذا هو القيمة الأساسية لنظام أنواع GraphQL: النموذج هو المصدر الموثوق لمساحة الواجهة.

أساسيات SDL: أنواع، استعلامات، وتعديلات

يُبنى كل ملف SDL من تعريفات الأنواع. إليك أصغر نموذج مفيد ممكن:

type Query {
  hello: String
}

Query هي نقطة الدخول للعمليات القرائية. يجب أن يكون هناك واحد على الأقل في كل نموذج. الحقل hello يُرجع String — أحد خمسة أنواع مبنية مسبقًا.

الخمسة أنواع المبنية مسبقًا هي:

  • سلسلة — نص مكتوب بتنسيق UTF-8
  • عدد صحيح — عدد صحيح موقوف بـ 32 بت
  • عدد عشري — عدد عشري بدقة مزدوجة
  • مُحَدَّد — صحيح أو خاطئ
  • بطاقة تعريف — معرف فريد، مُسلّم كسلسلة نصية

النماذج المُعادلة تُعرف بأنواع كائنات مخصصة. إليك نمطًا أكثر واقعية:

type User {
  id: ID!
  name: String!
  email: String!
  role: UserRole!
  posts: [Post!]!
}

type Post {
  id: ID!
  title: String!
  body: String
  author: User!
  publishedAt: DateTime
}

type Query {
  user(id: ID!): User
  posts: [Post!]!
}

يحدث الكثير في هذه 20 سطر. دعنا نُحلّلها.

مجالات غير مُسموحة وقوائم

ال ! بعد نوع يعني أن الحقل غير مسموح بالقيمة الصفرية — لن يُرجع null. بدون ذلك، يكون الحقل مسموحًا بالقيمة المفقودة، ويجب على العميل التعامل مع القيمة المفقودة. يُهم هذا التمييز أثناء التشغيل: إذا أدى مُحلّل حقل غير مسموح بالقيمة الصفرية إلى استثناء أو عودة قيمة صفرية، فإن GraphQL سيُنقل القيمة الصفرية إلى الأعلى، مما قد يُلغى الحقول الأعلى أيضًا.

تُستخدم الأقواس المربعة للقوائم: [Post] هي قائمة غير مسموحة من محتويات غير مسموحة. [Post!]! هي قائمة غير مسموحة من محتويات غير مسموحة. هذه هي النسخة التي تريدها عادةً — حقل يُرجع دائمًا مصفوفة (ربما فارغة)، وكل عنصر في المصفوفة هو كائن حقيقي، وليس صفرًا.

الأربعة مجموعات، مُوضحة:

  • [Post] — قائمة غير مسموحة، عناصر غير مسموحة (أقل استخدامًا)
  • [Post!] — قائمة غير مسموحة، عناصر غير مسموحة
  • [Post]! — قائمة غير مسموحة، عناصر غير مسموحة
  • [Post!]! — قائمة غير مسموحة، عناصر غير مسموحة (الأكثر شيوعًا)

التعديلات: كتابة البيانات

الاستعلامات قابلة للقراءة فقط. تُعالج التعديلات العمليات المُحررة. النوع Mutation مُصنّف بنفس الطريقة كما في Query، لكن بحسب التقاليد، تكون حقوله مُسببة لنتائج:

type Mutation {
  createPost(input: CreatePostInput!): Post!
  deletePost(id: ID!): Boolean!
}

يلاحظ CreatePostInput! — نوع مدخل، مما يؤدي مباشرة إلى المفهوم التالي.

أنواع المدخلات مقابل أنواع الناتج

هذا هو أحد أكثر النقاط تأثيرًا في نماذج GraphQL. لا يمكنك إعادة استخدام نوع كائن مثل كأحد المدخلات في التعديل. توجد في SDL نوعين منفصلين للأنواع لسبب معين: Post أنواع الكائنات

  • ) — تُستخدم في الاستجابات. يمكن أن تحتوي على مُحلّلين وتفاصيل حقول معقدة. (typeأنواع المدخلات
  • ) — تُستخدم في المدخلات. بيانات بسيطة، لا توجد مُحلّلين. يمكن أن تُشير الحقول فقط إلى أنواع مُدخلة أو أنواع مدخلة أخرى. (inputتُحافظ هذه التمييز على تحقق التحقق من المدخلات بشكل نظيف، وتمنع مشكلات الارتباط الدائري التي تنشأ إذا استُخدمت أنواع الناتج (التي يمكن أن تشير إلى بعضها البعض في أشكال معقدة) كمُدخلات مباشرة.
input CreatePostInput {
  title: String!
  body: String
  authorId: ID!
}

أنواع مخصصة

لا تغطي الخمسة أنواع المبنية مسبقًا كل شيء. مثل سلسلة تواريخ، أو عنوان URL، أو محتوى JSON — هذه تحتاج إلى أنواع مخصصة. تُعلن عنها على النحو التالي:

تُخبر SDL باسم الاستخدام. تقع عملية التسلسل، التحويل، والتحقق من المدخلات في تطبيق الخادم — وليس في ملف النموذج. تقدم مكتبات مثل

scalar DateTime
scalar JSON
scalar URL

أمثلة جاهزة لأنواع شائعة بحيث لا تحتاج إلى كتابتها من الصفر. graphql-scalars استخدم أنواع مخصصة عندما يكون

مُستندًا تقنيًا صحيحًا لكنه خاطئًا من حيث المعنى. يُعبّر الحقل المُصنّف كـ String عن المقصود؛ بينما يُجبر العميل على تخمين التنسيق. DateTime الأنواع المحدودة String تُقيّد الحقل إلى مجموعة محددة من القيم النصية. فهي أكثر موثوقية من النصوص الخام لأن النموذج يفرض القيم المسموحة على مستوى النوع:

الحقل المُصنّف كـ

لن يُرجع سلسلة غير متوقعة. يمكن أن يُرجع الحقل المُصنّف كـ

enum UserRole {
  ADMIN
  EDITOR
  VIEWER
}

enum PostStatus {
  DRAFT
  PUBLISHED
  ARCHIVED
}

أي شيء. استخدم الأنواع المحدودة عندما تكون المجموعة الممكنة معروفة، مستقرة، وذات معنى للعميل — فهي تجعل التحقق من النموذج أكثر فائدة. UserRole الواجهات والأنواع المجمعة String عندما يمكن أن يُرجع الحقل أنواع كائنات مختلفة، يُقدّم GraphQL ميكانيزمين: الواجهات والأنواع المجمعة.

الواجهات

تُحدد مجموعة متماسكة من الحقول. يجب أن تحتوي الأنواع التي تُنفذ الواجهة على هذه الحقول:

الأنواع المجمعة تُجمع الأنواع دون الحاجة إلى حقول مشتركة. وهي مفيدة عندما لا توجد أي توازي بنية بين الأنواع الممكنة:

interface Node {
  id: ID!
}

type User implements Node {
  id: ID!
  name: String!
}

type Post implements Node {
  id: ID!
  title: String!
}

يُستخدم العميل فراغات داخلية لمعالجة كل نوع في الواجهة أو النوع المجمّع: . إذا كنت تُرجع بيانات متعددة الأنواع، فاستخدم الواجهات عندما تشارك الأنواع الحقول، واستخدم الأنواع المجمعة عندما لا تشارك.

union SearchResult = User | Post | Comment

type Query {
  search(query: String!): [SearchResult!]!
}

التعليمات ... on User { name }تُغيّر السلوك على مستوى الحقل أو النوع. هناك نوعان مُدمجان في كل تطبيق GraphQL:

— يُشير إلى أن الحقل مُستبعد في التحقق من الواجهة

— شروط مُحددة من جانب العميل في الاستعلامات

  • @deprecated(reason: "Use newField instead") يمكنك أيضًا إنشاء تعليمات مخصصة لأشياء مثل حواجز التحقق، أو تلميحات التحكم في السرعة، أو تلميحات التخزين. تُعلن عنها في النموذج وتُنفذ على الخادم:
  • @skip(if: Boolean) و @include(if: Boolean) الفرق بين GraphQL وREST: متى تستخدم كل منهما؟

النهج الأولي للنماذج في GraphQL يُعطي نتائج مميزة في حالات محددة. فهو الخيار الصحيح عندما:

directive @auth(requires: UserRole = ADMIN) on FIELD_DEFINITION

type Mutation {
  deleteUser(id: ID!): Boolean! @auth(requires: ADMIN)
}

يحتاج عدة عمال (مواقع، تطبيقات موبايل، أطراف ثالثة) إلى مجموعات مختلفة من نفس البيانات

تريد تطوير الواجهة دون تسمية الأصداف — أضف الحقول بحرية، واحذف بدلًا من إزالتها

  • المنطقة ذاتها تُظهر شكلًا مُتسلسلًا مع علاقات معقدة بين الكيانات
  • تريد واجهة مُستندة ذات تحقق ذاتي يمكن للعملاء استكشافها من خلال التحقق من النموذج
  • أفضل استخدام REST عندما:
  • أنت تبني نقاط CRUD بسيطة مع محتويات مُتوقعة ومستوية

التخزين على طبقة HTTP أمر بالغ الأهمية — لا يمكن تخزين الطلب POST في GraphQL

  • الفرق بين الفريق صغير ومساحة الواجهة مستقرة — فإن تكلفة REST أقل
  • أنت تواجه مشكلة N+1 ولا ترغب في توصيل DataLoader لحلها
  • يُعتبر مشكلة N+1 أمرًا يستحق التوقف عنه. في مُحلّل GraphQL يُجلب
  • وكل مقالة من مقالات

، فإن التصميم البدائي يُنشئ طلبًا للقاعدة لكل مقالة لتحميل المُؤلف. مع 50 مقالة، هذا يعني 51 طلبًا لطلب واحد. لا يواجه REST هذه المشكلة لأنك تحكم بدقة ما يُنفذ من SQL لكل نقطة. في GraphQL، تُحل المشكلة باستخدام التجميع (DataLoader أو ما يعادلها) — وهي ممكنة، لكنها تُعدّ شيئًا إضافيًا يجب توصيله بشكل صحيح. posts تنسيق وتحقق من SDL authorتُجمع ملفات النماذج تدريجيًا على تباين التصاميم، ومسافات غير متسقة، وانحراف هيكلية مع تطور الفرق. قبل التزام التغييرات في النموذج، قم بتشغيلها من خلال مُصَّمّم لتعزيز التصاميم، وترتيب الحقول، وتحديد الأخطاء في التصاميم قبل أن تصل إلى نظام التحقق التلقائي.

يقوم iotools.cloud بالضبط هذا — قم بوضع نموذج SDL، واحصل على ناتج نظيف ومُصَّمّم بشكل متسق مع عرض الأخطاء في التحقق من التصاميم. يتعامل مع نماذج متعددة الأنواع، أنواع مخصصة، التعليمات، والحالات المُعقدة التي تُسبب توقفًا في التصاميم اليدوية. مفيد كمرحلة أخيرة قبل التزام أو مشاركة النموذج مع فريق آخر.

تُجمع ملفات التخطيط معاً ب(indentation) غير متسقة، ومسافات غير متطابقة، وانحرافات هيكلية مع تزايد الفرق. قبل التزام التغييرات في التخطيط، قم بمرورها عبر مُصَّمّم لتوازن المسافات، وترتيب الحقول، وتحديد الأخطاء في السياق قبل أن تصل إلى نظام CI.

ال GraphQL Schema Formatter على iotools.cloud يفعل هذا بالضبط — الصق ملفك SDL، واحصل على مخرج نظيف ومُصَّمّم بشكل متسق مع عرض أخطاء التحقق في الوقت الحقيقي. يتعامل مع التخطيطات المُتعددة الأنواع، والمقاييس المخصصة، والتعليمات، والحالات الحادة التي تُسبب أخطاء في التصيغ اليدوي. يُستخدم كمرحلة نهائية قبل التزام التخطيط أو مشاركته مع فريق آخر.

هل تريد حذف الإعلانات؟ تخلص من الإعلانات اليوم

تثبيت ملحقاتنا

أضف أدوات IO إلى متصفحك المفضل للوصول الفوري والبحث بشكل أسرع

أضف لـ إضافة كروم أضف لـ امتداد الحافة أضف لـ إضافة فايرفوكس أضف لـ ملحق الأوبرا

وصلت لوحة النتائج!

لوحة النتائج هي طريقة ممتعة لتتبع ألعابك، يتم تخزين جميع البيانات في متصفحك. المزيد من الميزات قريبا!

إعلان · حذف؟
إعلان · حذف؟
إعلان · حذف؟

ركن الأخبار مع أبرز التقنيات

شارك

ساعدنا على الاستمرار في تقديم أدوات مجانية قيمة

اشتري لي قهوة
إعلان · حذف؟