فهم استعلامات GraphQL
الاستعلامات هي كيفية جلب البيانات في GraphQL. تسمح للعملاء بتحديد البيانات التي يحتاجونها بالضبط، ويستجيب الخادم بتلك البيانات فقط. هذه واحدة من أقوى ميزات GraphQL - لا مزيد من جلب البيانات الزائدة أو الناقصة.
مفهوم رئيسي: استعلام GraphQL هو سلسلة نصية تصف البيانات التي تريد استرجاعها. يبدو مشابهاً لشكل البيانات التي تحصل عليها.
بناء جملة الاستعلام الأساسي
إليك استعلاماً بسيطاً لجلب اسم المستخدم وبريده الإلكتروني:
# الاستعلام
query {
user(id: "123") {
name
email
}
}
# الاستجابة
{
"data": {
"user": {
"name": "أحمد حسن",
"email": "ahmed@example.com"
}
}
}
تطابق الاستجابة بنية الاستعلام - هذه القابلية للتنبؤ تجعل GraphQL سهلة العمل معها.
الاستعلامات المتداخلة
واحدة من نقاط قوة GraphQL هي القدرة على جلب البيانات المرتبطة في استعلام واحد:
query {
user(id: "123") {
name
email
posts {
title
publishedAt
comments {
text
author {
name
}
}
}
}
}
يسترجع هذا الاستعلام الواحد المستخدم ومنشوراته والتعليقات على تلك المنشورات ومؤلفي التعليقات - كل ذلك في طلب واحد!
أفضل ممارسة: اجلب جميع البيانات التي تحتاجها في استعلام واحد بدلاً من إجراء طلبات متسلسلة متعددة. هذا يقلل من عبء الشبكة ويحسن الأداء.
وسائط الاستعلام
يمكنك تمرير وسائط إلى الحقول لتصفية النتائج أو فرزها أو تقسيمها:
query {
users(
limit: 10
offset: 0
orderBy: "createdAt"
role: ADMIN
) {
id
name
email
}
posts(
status: PUBLISHED
tags: ["graphql", "api"]
minViews: 100
) {
title
views
tags
}
}
أسماء مستعارة للحقول
تسمح لك الأسماء المستعارة بإعادة تسمية نتيجة حقل لتجنب تعارضات التسمية عند الاستعلام عن نفس الحقل عدة مرات:
query {
# الاستعلام عن نفس الحقل بوسائط مختلفة
recentPosts: posts(limit: 5, orderBy: "createdAt") {
title
createdAt
}
popularPosts: posts(limit: 5, orderBy: "views") {
title
views
}
# إعادة تسمية الحقول للوضوح
authorName: name
authorEmail: email
}
# الاستجابة
{
"data": {
"recentPosts": [...],
"popularPosts": [...],
"authorName": "أحمد حسن",
"authorEmail": "ahmed@example.com"
}
}
الأجزاء (Fragments)
تسمح لك الأجزاء بإعادة استخدام أجزاء شائعة من الاستعلامات. إنها مثل الدوال لاستعلاماتك:
# تعريف جزء
fragment UserInfo on User {
id
name
email
avatar
}
# استخدام الجزء
query {
user(id: "123") {
...UserInfo
posts {
title
author {
...UserInfo
}
}
}
allUsers {
...UserInfo
}
}
الأجزاء المضمنة مفيدة للاستعلام عن حقول على أنواع محددة عند التعامل مع الواجهات أو الاتحادات:
query {
search(query: "graphql") {
... on User {
name
email
}
... on Post {
title
content
}
... on Comment {
text
createdAt
}
}
}
نصيحة: تجعل الأجزاء استعلاماتك أكثر قابلية للصيانة وتقلل من التكرار. إنها ذات قيمة خاصة في التطبيقات الكبيرة ذات متطلبات البيانات المعقدة.
متغيرات الاستعلام
بدلاً من ترميز القيم في الاستعلامات، استخدم المتغيرات للقيم الديناميكية. هذا ضروري لتطبيقات العالم الحقيقي:
# تعريف الاستعلام بالمتغيرات
query GetUser($userId: ID!, $includeEmail: Boolean!) {
user(id: $userId) {
name
email @include(if: $includeEmail)
posts {
title
}
}
}
# تمرير المتغيرات بشكل منفصل
{
"userId": "123",
"includeEmail": true
}
بناء جملة المتغير:
$variableName - يبدأ إعلان المتغير بـ $
ID! - تعليق النوع (معرف غير قابل للقيمة الفارغة)
- يتم تمرير المتغيرات في كائن JSON منفصل
فائدة الأمان: تمنع المتغيرات هجمات حقن الاستعلام وتسمح لخوادم GraphQL بتخزين الاستعلامات المحللة بشكل أكثر فعالية.
قيم المتغيرات الافتراضية
يمكنك توفير قيم افتراضية للمتغيرات:
query GetPosts(
$limit: Int = 10
$offset: Int = 0
$status: PostStatus = PUBLISHED
) {
posts(limit: $limit, offset: $offset, status: $status) {
title
status
createdAt
}
}
# إذا لم تمرر المتغيرات، يتم استخدام القيم الافتراضية
{}
التوجيهات (Directives)
تعدل التوجيهات تنفيذ الاستعلامات. تتضمن GraphQL توجيهين مدمجين:
@include(if: Boolean) - تضمين الحقل إذا كان الشرط صحيحاً:
query GetUser($userId: ID!, $includeEmail: Boolean!) {
user(id: $userId) {
name
email @include(if: $includeEmail)
posts {
title
}
}
}
# المتغيرات
{
"userId": "123",
"includeEmail": false # لن يتم تضمين حقل البريد الإلكتروني
}
@skip(if: Boolean) - تخطي الحقل إذا كان الشرط صحيحاً:
query GetUser($userId: ID!, $skipPosts: Boolean!) {
user(id: $userId) {
name
email
posts @skip(if: $skipPosts) {
title
content
}
}
}
# المتغيرات
{
"userId": "123",
"skipPosts": true # سيتم تخطي حقل المنشورات
}
ملاحظة: لا يمكن استخدام @include و @skip على نفس الحقل. اختر الذي يجعل منطقك أكثر وضوحاً.
أسماء العمليات
من أفضل الممارسات تسمية استعلاماتك لتسهيل التصحيح والتسجيل:
# استعلام مسمى
query GetUserProfile($userId: ID!) {
user(id: $userId) {
name
email
bio
}
}
# استعلام مجهول (غير موصى به للإنتاج)
query {
user(id: "123") {
name
}
}
الاستبطان (Introspection)
يسمح لك نظام الاستبطان في GraphQL بالاستعلام عن المخطط نفسه. هذا يشغل أدوات مثل GraphiQL و Apollo Studio:
# الحصول على جميع الأنواع في المخطط
{
__schema {
types {
name
kind
}
}
}
# الحصول على تفاصيل حول نوع محدد
{
__type(name: "User") {
name
fields {
name
type {
name
kind
}
}
}
}
# الحصول على جميع عمليات الاستعلام
{
__schema {
queryType {
fields {
name
description
args {
name
type {
name
}
}
}
}
}
}
نصيحة أمنية: في الإنتاج، قد ترغب في تعطيل الاستبطان لمنع الكشف عن مخططك الكامل للمهاجمين المحتملين.
أفضل ممارسات الاستعلام
- قم دائماً بتسمية استعلاماتك - يسهل التصحيح والتسجيل
- استخدم الأجزاء - قلل من التكرار وحسّن قابلية الصيانة
- استخدم المتغيرات - لا تقم أبداً بتضمين القيم في سلاسل الاستعلام
- اطلب الحقول المطلوبة فقط - لا تطلب بيانات لن تستخدمها
- قسّم القوائم الكبيرة - استخدم limit/offset أو التقسيم المستند إلى المؤشر
- ضع في اعتبارك عمق الاستعلام - يمكن أن تؤثر الاستعلامات المتداخلة بعمق على الأداء
تمرين: اكتب استعلام GraphQL لتطبيق تجارة إلكترونية مع المتطلبات التالية:
- جلب 20 منتجاً مع دعم التقسيم
- التصفية حسب الفئة ونطاق السعر
- تضمين اسم المنتج والسعر والوصف والصور
- لكل منتج، قم بتضمين اسم البائع وتقييمه
- استخدم متغيرات الاستعلام للتصفية الديناميكية
- أضف خياراً لتضمين مراجعات المنتج بشكل مشروط باستخدام توجيه
- استخدم جزءاً للحقول الشائعة للمنتج
ملخص
في هذا الدرس، تعلمت كيفية كتابة استعلامات GraphQL، من اختيار الحقول الأساسي إلى الميزات المتقدمة مثل الأجزاء والمتغيرات والتوجيهات. الاستعلامات هي الطريقة الأساسية التي يتفاعل بها العملاء مع واجهة برمجة تطبيقات GraphQL الخاصة بك، وإتقانها ضروري لبناء تطبيقات فعالة.