اختار المؤلف صندوق التبرعات الحرة ومفتوحة المصدر ليتلقى تبرعًا كجزء من برنامج كتابة للتبرعات.
المقدمة
GraphQL هو حلاً حديثًا لتسهيل التواصل بين واجهة مستخدم أمامية ومصدر بيانات. تُوضَّح كافة التفاصيل والقدرات لتنفيذ GraphQL في المخطط الشمي لـ GraphQL. من أجل كتابة مخطط GraphQL يعمل، يجب أن تفهم نظام أنواع GraphQL.
في هذا المقال، ستتعرف على أنواع GraphQL: الأنواع المدمجة الخمسة الطرفية، Enums، وأنواع التغليف القائمة وغير القائمة، أنواع الكائنات، وأنواع الواجهة والاتحاد الواقعة في الجانب المجرد منها. ستستعرض أمثلة لكل نوع وستتعلم كيفية استخدامها لبناء مخطط GraphQL كامل.
المتطلبات
للحصول على أقصى استفادة من هذا البرنامج التعليمي، يجب عليك أن تكون قد:
- فهمت المفاهيم الأساسية لـ GraphQL، التي يتم توضيحها في مقدمة لـ GraphQL.
- A GraphQL environment, an example of which can be found in How to Set Up a GraphQL API Server in Node.js.
أنواع السكالار
كل البيانات في مخطط GraphQL تقوم في النهاية بالتحليل إلى مجموعة متنوعة من أنواع السكالار، التي تمثل القيم الأساسية. يمكن تمثيل استجابات GraphQL على شكل شجرة، وأنواع السكالار هي الأوراق في نهاية الشجرة. يمكن أن يكون هناك العديد من المستويات في استجابة متداخلة، ولكن المستوى الأخير سيتم حله دائمًا إلى نوع سكالار (أو Enum). يأتي GraphQL مع خمسة أنواع سكالار مدمجة: Int
، Float
، String
، Boolean
، و ID
.
Int
Int
هو قيمة رقمية موقعة بحجم 32 بت غير كسرية. إنها عدد صحيح موقع (إيجابي أو سلبي) ولا يتضمن الأعداد العشرية. القيمة القصوى للعدد الصحيح بحجم 32 بت هي 2،147،483،647
. هذا هو واحد من النوعين المدمجين المستخدمين لبيانات الأرقام.
Float
A Float
is a signed double-precision fractional value. It is a signed (positive or negative) number that contains a decimal point, such as 1.2
. This is the other built-in scalar used for numerical data.
String
A String
is a UTF-8 character sequence. The String
type is used for any textual data. This can also include data like very large numbers. Most custom scalars will be types of string data.
Boolean
A Boolean
is a true
or false
value.
ID
يعتبر ID
معرفًا فريدًا. يتم تسلسل هذه القيمة دائمًا كسلسلة نصية، حتى إذا كان ID
رقميًا. قد يتم تمثيل نوع ID
بشكل شائع باستخدام معرف فريد عالمي (UUID).
المقادير المخصصة
بالإضافة إلى هذه المقادير المدمجة، يمكن استخدام الكلمة الرئيسية scalar
لتعريف مقدار مخصص. يمكنك استخدام المقادير المخصصة لإنشاء أنواع تحتوي على التحقق من صحة مستوى الخادم الإضافي، مثل Date
، Time
، أو Url
. فيما يلي مثال على تعريف نوع Date
جديد:
scalar Date
سيعرف الخادم كيفية التعامل مع التفاعلات مع هذا النوع الجديد باستخدام GraphQLScalarType
.
نوع التعداد
نوع Enum، المعروف أيضًا باسم نوع Enumerator، يصف مجموعة من القيم الممكنة.
باستخدام موضوع واجهة برمجة التطبيقات للعبة Fantasy من دورات تعليمية أخرى في سلسلة كيفية إدارة البيانات باستخدام GraphQL، قد تقوم بإنشاء enum
لشخصيات اللعبة Job
و Species
بجميع القيم التي سيقبلها النظام لهم. يتم تعريف التعداد باستخدام الكلمة الرئيسية enum
، كما يلي:
"The job class of the character."
enum Job {
FIGHTER
WIZARD
}
"The species or ancestry of the character."
enum Species {
HUMAN
ELF
DWARF
}
بهذه الطريقة ، يتم ضمان أن مهمة الشخصية هي “مقاتل” أو “ساحر” ولا يمكن أن تكون عن طريق الصدفة “بنفسجي” أو سلسلة عشوائية أخرى ، وهو ما يمكن أن يحدث إذا تم استخدام نوع “سلسلة” بدلاً من إنشاء Enum مخصص. يتم كتابة الـEnums بأحرف كبيرة بحسب التقليد.
يمكن أيضًا استخدام Enums كقيم مقبولة في الوسائط. على سبيل المثال ، يمكنك إنشاء Enum لـ “اليد” لتحديد ما إذا كان السلاح مفرد اليد (مثل السيف القصير) أو مزدوج اليد (مثل الفأس الثقيل) ، واستخدم ذلك لتحديد ما إذا كان يمكن تجهيز واحد أو اثنين:
enum Hand {
SINGLE
DOUBLE
}
"A valiant weapon wielded by a fighter."
type Weapon {
name: String!
attack: Int
range: Int
hand: Hand
}
type Query {
weapons(hand: Hand = SINGLE): [Weapon]
}
تم تعريف Enum “اليد” بالقيم “مفرد” و “مزدوج” ، والوسيطة في حقل “الأسلحة” لديها قيمة افتراضية “مفرد” ، وهذا يعني إذا لم يتم تمرير وسيطة فإنها ستعود إلى “مفرد”.
نوع غير قابل للقبول
قد تلاحظ أن “null” أو “undefined” ، النوع الشائع الذي يعتبره العديد من اللغات نوعًا أساسيًا ، غير موجود في قائمة القيم الأساسية المدمجة. “null” موجود في GraphQL ويمثل عدم وجود قيمة.
جميع أنواع البيانات في GraphQL قابلة للتألفاف افتراضيًا وبالتالي null
هو استجابة صالحة لأي نوع. من أجل جعل قيمة مطلوبة، يجب تحويلها إلى نوع GraphQL غير قابل للتألفاف باستخدام علامة تعجب آخر النوع. النوع غير القابل للتألفاف يُعرف كنوع تعديل، والتي تستخدم لتعديل النوع الذي يُشير إليه. على سبيل المثال، String
هو سلسلة اختيارية (أو قابلة للتألفاف)، و String!
هي سلسلة مطلوبة (أو غير قابلة للتألفاف).
نوع القائمة
A List type in GraphQL is another type modifier. Any type that is wrapped in square brackets ([]
) becomes a List type, which is a collection that defines the type of each item in a list.
على سبيل المثال، يتم تعريف نوع ك [Int]
على أنه مجموعة من أنواع Int
، و [String]
ستكون مجموعة من أنواع String
. يمكن استخدام غير القابل للتألفاف والقائمة معًا لجعل النوع مطلوبًا ومعرفًا كقائمة، مثل [String]!
.
نوع الكائن
إذا كانت الأنواع العلمية في GraphQL تصف “الأوراق” في نهاية الاستجابة التسلسلية الهرمية في GraphQL، فإن أنواع الكائن تصف الـ “فروع” الوسيطة، وتقريبًا كل شيء في مخطط GraphQL هو نوع من أنواع الكائن.
الكائنات تتكون من قائمة من الحقول المسماة (المفاتيح) ونوع القيمة التي سيتم حساب كل حقل عليها. يتم تعريف الكائنات باستخدام الكلمة الرئيسية type
. يجب تعريف حقل واحد على الأقل، ولا يمكن أن يبدأ الحقل بنجمتين (__
) لتجنب التضارب مع نظام استطلاع GraphQL.
في مثال واجهة برمجة تطبيقات الألعاب الخيالية GraphQL، يمكنك إنشاء كائن Fighter
لتمثيل نوع من الشخصيات في لعبة:
"A hero with direct combat ability and strength."
type Fighter {
id: ID!
name: String!
level: Int
active: Boolean!
}
في هذا المثال، تم تعريف نوع الكائن Fighter
، ويحتوي على أربعة حقول مسماة:
id
ينتج نوعID
غير قابل للإلغاء.name
ينتج نوعString
غير قابل للإلغاء.level
ينتج نوعInt
.active
ينتج نوعBoolean
غير قابل للإلغاء.
يمكنك أيضًا إضافة تعليق أعلى التعريف باستخدام علامات الاقتباس المزدوجة، كما في هذا المثال: "بطل ذو قدرة قتالية مباشرة وقوة."
. سيظهر هذا كوصف للنوع.
في هذا المثال، يحسب كل حقل على نوع مبعثر، ولكن يمكن أيضًا لحقول الكائن أن تحسب إلى أنواع كائن أخرى. على سبيل المثال، يمكنك إنشاء نوع Weapon
، ويمكن إعداد مخطط GraphQL حيث سيحسب حقل weapon
على الكائن Fighter
إلى كائن Weapon
:
"A valiant weapon wielded by a fighter."
type Weapon {
name: String!
attack: Int
range: Int
}
"A hero with direct combat ability and strength."
type Fighter {
id: ID!
name: String!
level: Int
active: Boolean!
weapon: Weapon
}
يمكن أيضًا تضمين الكائنات في حقول الكائنات الأخرى.
أنواع عمليات الجذر
هناك ثلاثة كائنات خاصة تعمل كنقاط دخول إلى مخطط GraphQL: الاستعلام، التحويل، والاشتراك. هذه تُعرف باسم أنواع عمليات الجذر وتتبع كل القواعد نفسها كأي نوع كائن آخر.
الكلمة المفتاحية schema
تمثل نقطة الدخول إلى مخطط GraphQL. سيتم وضع أنواع الاستعلام، التحويل، والاشتراك الجذرية على كائن schema
الجذر:
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
نوع الاستعلام مطلوب على أي مخطط GraphQL ويمثل طلب قراءة، مماثل لطلب GET
في واجهة برمجة تطبيق REST. فيما يلي مثال على كائن استعلام جذري يُرجع قائمة من أنواع Fighter
:
type Query {
fighters: [Fighter]
}
التحويلات تمثل طلب كتابة، والتي يمكن أن تكون مشابهة لـ POST
، PUT
، أو DELETE
في واجهة برمجة تطبيق REST. في المثال التالي، يحتوي Mutation
على حقل addFighter
بمُعرف واحد (input
):
type Mutation {
addFighter(input: FighterInput): Fighter
}
أخيرًا، الاشتراك يُقابل تيار حدث، والذي يمكن استخدامه بالتزامن مع Websocket في تطبيق ويب. في API الخيال GraphQL، ربما يمكن استخدامه للتصادمات العشوائية في المعارك، مثل ما يلي:
type Subscription {
randomBattle(enemy: Enemy): BattleResult
}
لاحظ أن نقطة الدخول schema
غالبًا ما يتم تجريدها في بعض تنفيذات GraphQL.
وسيطة الحقول
حقول كائن GraphQL هي في الأساس وظائف تعيد قيمة، ويمكنها قبول وسيطات مثل أي وظيفة. يتم تعريف وسيطات الحقول بواسطة اسم الوسيط تليه النوع. يمكن أن تكون الوسيطات أي نوع غير كائن. في هذا المثال، يمكن تصفية كائن Fighter باستخدام حقل id (الذي يحل إلى نوع ID غير قابل للإلغاء):
type Query {
fighter(id: ID!): Fighter
}
هذا المثال مفيد بشكل خاص لاسترجاع عنصر واحد من مخزن البيانات، ولكن يمكن أيضًا استخدام الوسيطات للتصفية، وتقسيم الصفحات، والاستعلامات الأكثر تحديدًا الأخرى.
نوع الواجهة
مثل نوع الكائن، يتكون نوع الواجهة الفعلي من قائمة من الحقول المسماة وأنواع القيم المرتبطة بها. تبدو الواجهات مثل الكائنات وتتبع كل القواعد نفسها ولكن تستخدم لتحديد مجموعة فرعية من تنفيذ الكائنات.
حتى الآن في مخططك ، لديك كائن “Fighter” ولكن ربما ترغب أيضًا في إنشاء كائن “Wizard” و “Healer” وكائنات أخرى ستشترك في العديد من الحقول نفسها ولكنها ستحتوي على اختلافات بسيطة. في هذه الحالة ، يمكنك استخدام واجهة لتعريف الحقول المشتركة بينهم جميعًا وإنشاء كائنات تكون تنفيذات لهذه الواجهة.
في المثال التالي ، يمكنك إنشاء واجهة “BaseCharacter” باستخدام الكلمة الرئيسية “interface” وتحتوي على جميع الحقول التي ستمتلكها جميع أنواع الشخصيات:
"A hero on a quest."
interface BaseCharacter {
id: ID!
name: String!
level: Int!
species: Species
job: Job
}
جميع أنواع الشخصيات ستحتوي على الحقول “id” و “name” و “level” و “species” و “job”.
الآن ، تخيل أن لديك نوع “Fighter” ونوع “Wizard” اللذين لديهما هذه الحقول المشتركة ، ولكن “Fighters” يستخدمون “Weapon” و “Wizards” يستخدمون “Spells”. يمكنك استخدام الكلمة الرئيسية “implements” لتحديد كل منهما كتنفيذ لـ “BaseCharacter” ، مما يعني أنه يجب أن يحتوي على جميع الحقول من الواجهة المُنشأة:
"A hero with direct combat ability and strength."
type Fighter implements BaseCharacter {
id: ID!
name: String!
level: Int!
species: Species
job: Job!
weapon: Weapon
}
"A hero with a variety of magical powers."
type Wizard implements BaseCharacter {
id: ID!
name: String!
level: Int!
species: Species
job: Job!
spells: [Spell]
}
“Fighter” و “Wizard” هما تنفيذات صالحة لواجهة “BaseCharacter” لأن لديهما مجموعة الحقول المطلوبة.
نوع الاتحاد
نوع مجرد آخر يمكن استخدامه مع الكائنات هو نوع الاتحاد. باستخدام الكلمة الرئيسية union
، يمكنك تعريف نوع بقائمة من الكائنات التي تعتبر جميعها صالحة كإجابات.
باستخدام الواجهات التي تم إنشاؤها في القسم السابق، يمكنك إنشاء اتحاد Character
يعرف الشخصية كـ Wizard
أو Fighter
:
union Character = Wizard | Fighter
يحدد الرمز (=) المساواة التعريف، ويعمل الرمز العمودي (|) كبيان OR
. يرجى ملاحظة أن الاتحاد يجب أن يتكون من كائنات أو واجهات. أنواع الطلاء ليست صالحة في الاتحاد.
الآن إذا كان لديك استعلام عن قائمة من الشخصيات، يمكن استخدام اتحاد Character
وإرجاع جميع الأنواع Wizard
و Fighter
.
الاستنتاج
في هذا الدورة التعليمية، تعلمت العديد من الأنواع التي تحدد نظام أنواع GraphQL. الأنواع الأساسية هي الأنواع الجزئية، التي تعتبر القيم التي تعمل كأوراق في شجرة السياق، وتتألف من Int
، Float
، String
، Boolean
، ID
، وأي نوع جزئي مخصص يقرر تنفيذ GraphQL إنشاؤه. العناصر هي قوائم من القيم الثابتة الصالحة التي يمكن استخدامها عندما تحتاج إلى مزيد من التحكم في الاستجابة بدلاً من تعريفها ببساطة كـ String
، وهي أيضًا أوراق في شجرة السياق. القوائم وأنواع Non-Null هي أنواع تعديلية تعرف أحيانًا باسم نوع التغليف، ويمكنها تحديد أنواع أخرى كمجموعات أو مطلوبة، على التوالي. الكائنات هي فروع شجرة السياق، وتقريبًا كل شيء في نظام أنواع GraphQL هو نوع من الكائن، بما في ذلك query
، mutation
، و subscription
نقاط الدخول. واجهة وأنواع الاتحاد هي أنواع مجردة يمكن أن تكون مفيدة في تحديد الكائنات.
للمزيد من التعلم، يمكنك ممارسة إنشاء وتعديل نظام أنواع GraphQL عن طريق قراءة كيفية إعداد خادم واجهة برمجة التطبيقات GraphQL في Node.js للحصول على بيئة خادم GraphQL تعمل.
Source:
https://www.digitalocean.com/community/conceptual-articles/understanding-the-graphql-type-system