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

ماذا ستتعلم في هذا الدليل؟
- إعداد مشروع بسيط يتكون من عميل وخادم.
- تعريف مخطط
SchemaفيGraphQL. - إضافة دوال
Resolverلمعالجة الطلبات. - تشغيل خادم باستخدام
Apollo Server. - إنشاء عميل بسيط يجلب البيانات من الخادم.
- عرض البيانات داخل الصفحة بشكل مباشر.
البدء في إعداد المشروع
تثبيت Node.js وإنشاء هيكل المجلدات
قبل أي شيء، تأكد من تثبيت Node.js على جهازك. بعد ذلك، أنشئ مشروعاً يحتوي على مجلدين: أحدهما للعميل والآخر للخادم.
📁 project
├── 📁 client
└── 📁 server
بعد إنشاء البنية الأساسية، انتقل إلى مجلد server وشغّل أمر تهيئة المشروع:
npm init
وإذا كنت تريد إنشاء الملف بسرعة دون المرور بالأسئلة التفاعلية، استخدم:
npm init -y
هذا الأمر ينشئ ملف package.json الذي سيحتوي على إعدادات المشروع واعتماداته.
تثبيت الحزم الأساسية
نحتاج أولاً إلى تثبيت مكتبة graphql، وهي المسؤولة عن بناء المخطط ومعالجة الاستعلامات:
npm install graphql
بعدها نثبّت apollo-server لأنه يوفّر طبقة جاهزة لتشغيل خادم GraphQL بسهولة:
npm install apollo-server
من المهم أن تعرف أن Apollo ليس مجرد أداة واحدة، بل منظومة متكاملة للعمل مع GraphQL. وأكثر جزأين شيوعاً فيها هما:
Apollo Client: للتعامل مع الواجهة الأمامية وجلب البيانات منGraphQL API.Apollo Server: لإنشاء الخادم ومعالجة الاستعلامات والإجابات.
كيف تعرّف GraphQL Schema؟
يمثل Schema العمود الفقري لأي تطبيق GraphQL. فهو يحدد شكل البيانات المتاحة، وأنواعها، والحقول الموجودة داخل كل نوع، إضافة إلى العمليات التي يمكن للعميل تنفيذها مثل Query وMutation.
على سبيل المثال، لو أردت تصميم تطبيق موسيقي بسيط، فقد تكتب مخططاً يحتوي على النوعين Song وAuthor بهذا الشكل:
type Song {
title: String
author: Author
}
type Author {
name: String
songs: [Song]
}
ثم تضيف نوع Query لتعريف الاستعلامات المتاحة:
type Query {
getSongs: [Song]
getAuthors: [Author]
}
لكن بما أن هدفنا هنا هو الفهم السريع والبناء التدريجي، سنبدأ بمثال أبسط يعيد رسالة نصية فقط:
type Query {
greeting: String
}
الآن أنشئ ملف server.js داخل مجلد server:
📁 project
├── 📁 client
└── 📁 server
└── 📄 server.js
وفي هذا الملف نستورد الدالة gql من apollo-server لكتابة المخطط:
const { gql } = require('apollo-server');
const typeDefs = gql`
type Query {
greeting: String
}
`;
تقوم gql بتحويل النص المكتوب إلى بنية يفهمها الخادم، وتُعرف هذه البنية عادة باسم Abstract Syntax Tree أو AST.
كيف تضيف Resolver لمعالجة الاستعلامات؟
بعد تعريف المخطط، نحتاج إلى تحديد الطريقة التي ستُجلب بها البيانات. هنا يأتي دور Resolver، وهو دالة مسؤولة عن إرجاع القيمة المناسبة لكل حقل في المخطط.
بما أن لدينا حقلاً واحداً فقط اسمه greeting ويعيد قيمة من النوع String، فإن دالة المعالجة ستكون مباشرة:
const resolvers = {
Query: {
greeting: () => 'Hello GraphQL world!👋',
},
};
في المشاريع الحقيقية، غالباً ما تتصل هذه الدوال بقاعدة بيانات أو خدمة خارجية أو طبقة أعمال داخلية، لكن المثال الحالي يركّز على الفكرة الأساسية فقط.
إعداد الخادم باستخدام Apollo Server
الآن سنجمع بين typeDefs وresolvers داخل كائن ApolloServer ثم نبدأ تشغيل الخادم على منفذ محدد.
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Query {
greeting: String
}
`;
const resolvers = {
Query: {
greeting: () => 'Hello GraphQL world!👋',
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen({ port: 9000 }).then(({ url }) =>
console.log(`Server running at ${url}`)
);
بعد حفظ الملف، شغّل الخادم بالأمر التالي:
node server/server.js
وعند نجاح التشغيل، ستظهر لك رسالة مشابهة لهذه:
~/graphql-hello-world-server > node server/server.js
Server running at http://localhost:9000/
وهنا يصبح خادم GraphQL جاهزاً لاستقبال الطلبات.
ما هي واجهة GraphQL Playground؟
عند فتح الرابط http://localhost:9000/ في المتصفح، ستظهر لك واجهة تفاعلية جاهزة تُعرف باسم GraphQL Playground. هذه الواجهة تعمل كبيئة اختبار داخل المتصفح، وتمكّنك من تنفيذ استعلامات Query وعمليات Mutation بسهولة دون الحاجة إلى أدوات خارجية.

إذا كنت معتاداً على أدوات مثل Postman، فستجد أن GraphQL Playground يؤدي دوراً مشابهاً، لكنه مخصص لتجربة واجهات GraphQL بشكل أسرع وأكثر وضوحاً.
جرّب تنفيذ الاستعلام التالي في اللوحة اليسرى:
query {
greeting
}
بعد الضغط على زر التشغيل، ستظهر النتيجة في الجهة اليمنى.


إعداد العميل Client
إنشاء ملف client.html
بعد تشغيل الخادم، ننتقل الآن إلى جزء العميل. داخل مجلد client، أنشئ ملفاً باسم client.html:
📁 project
├── 📁 client
│ └── 📄 client.html
└── 📁 server
└── 📄 server.js
وسيحتوي الملف على بنية HTML أساسية مع عنوان مؤقت لإظهار حالة التحميل:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hello World GraphQL Client</title>
</head>
<body>
<h1>Loading...</h1>
<script src="app.js"></script>
</body>
</html>
كيف تجلب البيانات من الخادم؟
إنشاء ملف app.js
في المجلد نفسه، أنشئ ملف app.js ليحتوي على منطق جلب البيانات:
📁 project
├── 📁 client
│ ├── 📄 client.html
│ └── 📄 app.js
└── 📁 server
└── 📄 server.js
داخل هذا الملف، نحدد أولاً رابط خادم GraphQL:
const GRAPHQL_URL = 'http://localhost:9000/';
بعدها نكتب دالة غير متزامنة باسم fetchGreeting() تستخدم fetch API لإرسال طلب POST إلى الخادم:
async function fetchGreeting() {
const response = await fetch(GRAPHQL_URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
query: `
query {
greeting
}
`,
}),
});
const responseBody = await response.json();
console.log(responseBody);
}
قد يبدو استخدام POST غريباً إذا كنت قادماً من عالم REST، لأن طلب قراءة البيانات هناك يُرسل غالباً باستخدام GET. لكن في GraphQL تُرسل الاستعلامات عادة داخل body، ولهذا نستخدم POST في أغلب الحالات.
بعد ذلك يمكنك استدعاء الدالة مباشرة:
const GRAPHQL_URL = 'http://localhost:9000/';
async function fetchGreeting() {
const response = await fetch(GRAPHQL_URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
query: `
query {
greeting
}
`,
}),
});
const responseBody = await response.json();
console.log(responseBody);
}
fetchGreeting();
إذا فتحت الصفحة في المتصفح ثم راقبت وحدة التحكم Console داخل أدوات المطور، فسترى أن الرد يحتوي على البيانات القادمة من الخادم.

كيف تعرض البيانات داخل الصفحة؟
بعد التأكد من نجاح الاتصال، نحدّث الكود بحيث يعيد فقط الكائن data بدلاً من طباعة كامل الرد.
استبدل هذا الجزء:
const responseBody = await response.json();
console.log(responseBody);
بهذا:
const { data } = await response.json();
return data;
ثم حدّث عنوان الصفحة باستخدام القيمة الموجودة في greeting:
fetchGreeting().then(({ greeting }) => {
const title = document.querySelector('h1');
title.textContent = greeting;
});
ليصبح ملف app.js كاملاً بالشكل التالي:
const GRAPHQL_URL = 'http://localhost:9000/';
async function fetchGreeting() {
const response = await fetch(GRAPHQL_URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
query: `
query {
greeting
}
`,
}),
});
const { data } = await response.json();
return data;
}
fetchGreeting().then(({ greeting }) => {
const title = document.querySelector('h1');
title.textContent = greeting;
});
النتيجة النهائية هي أن النص Loading... سيتحوّل تلقائياً إلى الرسالة القادمة من الخادم.

لماذا يُعد GraphQL مناسباً للتطبيقات الحديثة؟
- يوفر نقطة وصول واحدة بدلاً من تعدد المسارات.
- يسمح للعميل بطلب الحقول التي يحتاجها فقط.
- يقلل من مشكلة الجلب الزائد أو الناقص للبيانات.
- يسهّل تطوير تطبيقات الويب والجوال المعتمدة على البيانات.
- يتكامل بسلاسة مع أدوات قوية مثل
Apollo ServerوApollo Client.
ملاحظات عملية للمبتدئين
- ابدأ بمخطط صغير جداً قبل الانتقال إلى العلاقات المعقدة بين الأنواع.
- احرص على مطابقة كل
Resolverللتعريف الموجود فيSchema. - اختبر الاستعلامات أولاً عبر
GraphQL Playgroundقبل ربطها بالواجهة. - نظّم المشروع من البداية إلى مجلدات واضحة مثل
clientوserver. - عند بناء مشروع أكبر، افصل الأنواع والاستعلامات والمحللات في ملفات مستقلة لسهولة الصيانة.
مصادر مفيدة للتوسع في GraphQL
- الموقع الرسمي لـ
GraphQLلفهم المفاهيم الأساسية والمتقدمة. - توثيق
Apolloللتعمق في إعداد الخوادم والعملاء. - أدوات مثل
GraphQL PlaygroundوامتداداتVSCodeلتحسين تجربة التطوير. - دورات تطبيقية تركّز على بناء تطبيقات كاملة باستخدام
Node.jsوReact.
الخلاصة التقنية
يمنحك الجمع بين GraphQL وNode.js بداية قوية لبناء واجهات برمجة تطبيقات مرنة وسهلة التطوير. هذا المثال البسيط يوضح الفكرة الجوهرية: تعريف مخطط واضح، ربطه بدوال Resolver، ثم استهلاك البيانات من جهة العميل بكفاءة. تقنياً، يُعد هذا الأسلوب مناسباً جداً عندما تحتاج التطبيقات إلى تحكم دقيق في البيانات المعروضة وتقليل عدد الطلبات والتعقيد في الواجهة الخلفية.