كيفية جلب البيانات في React من واجهة GraphQL API: 5 طرق عملية ومقارنة تقنية
إذا كنت تبني تطبيقاً باستخدام React وتحتاج إلى الاتصال بواجهة GraphQL API، فهناك أكثر من أسلوب يمكن الاعتماد عليه لتحقيق ذلك بكفاءة. في هذا الدليل العملي، سنستعرض خمس طرق شائعة وفعالة لجلب البيانات، بدءاً من المكتبات المتقدمة مثل Apollo Client وurql، وصولاً إلى الحلول الأخف مثل React Query مع fetch API.
الهدف هنا ليس فقط عرض الأكواد، بل مساعدتك على فهم الفروق بين كل خيار، ومتى يكون مناسباً لمشروعك، مع الحفاظ على محتوى واضح، احترافي، وسهل التطبيق.

البدء: مثال عملي باستخدام واجهة SpaceX
في الأمثلة التالية سنستخدم واجهة SpaceX GraphQL API لجلب آخر 10 عمليات إطلاق سابقة. هذا المثال مناسب لفهم الفكرة بسرعة، ويمكنك تكييفه بسهولة مع أي واجهة GraphQL أخرى داخل مشروعك.
سنرتب الطرق من الأكثر شمولاً إلى الأبسط من حيث الإعداد والتنفيذ.
1. استخدام Apollo Client في React
تُعد مكتبة Apollo Client من أشهر الأدوات للتعامل مع GraphQL داخل تطبيقات React. وتمتاز بأنها لا تقتصر على جلب البيانات من الخادم فقط، بل توفر أيضاً نظام تخزين مؤقت cache وإدارة حالة متقدمة على مستوى التطبيق.
تثبيت الحزم المطلوبة
npm install @apollo/client graphql
تهيئة العميل وربطه بالتطبيق
الفكرة الأساسية هي إنشاء كائن من ApolloClient وتزويده بعنوان نقطة النهاية uri بالإضافة إلى ذاكرة التخزين InMemoryCache، ثم تمريره إلى كامل شجرة المكونات عبر ApolloProvider.
import React from "react";
import ReactDOM from "react-dom";
import { ApolloProvider, ApolloClient, InMemoryCache } from "@apollo/client";
import App from "./App";
const client = new ApolloClient({
uri: "https://api.spacex.land/graphql/",
cache: new InMemoryCache()
});
const rootElement = document.getElementById("root");
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
rootElement
);
تنفيذ الاستعلام عبر useQuery
بعد التهيئة، يمكنك استخدام الخطاف useQuery لتنفيذ أي استعلام. كما تُستخدم الدالة gql لكتابة الاستعلام بصيغة مفهومة ومهيأة بشكل جيد داخل المحرر.
import React from "react";
import { useQuery, gql } from "@apollo/client";
const FILMS_QUERY = gql`
{
launchesPast(limit: 10) {
id
mission_name
}
}
`;
export default function App() {
const { data, loading, error } = useQuery(FILMS_QUERY);
if (loading) return "Loading...";
if (error) return <pre>{error.message}</pre>;
return (
<div>
<h1>SpaceX Launches</h1>
<ul>
{data.launchesPast.map((launch) => (
<li key={launch.id}>{launch.mission_name}</li>
))}
</ul>
</div>
);
}
متى تكون Apollo Client خياراً مناسباً؟
- عندما تحتاج إلى بيئة متكاملة للتعامل مع
GraphQL. - إذا كان مشروعك كبيراً ويعتمد على التخزين المؤقت بكثافة.
- عندما تريد دعم الاستعلامات
queriesوالتعديلاتmutationsوالاشتراكاتsubscriptionsفي مكتبة واحدة.
2. استخدام urql كحل أخف من Apollo
مكتبة urql توفر تجربة قريبة من Apollo ولكن بحجم أخف وإعداد أقل. وهي مناسبة للمطورين الذين يريدون التعامل مع GraphQL بشكل منظم دون الاعتماد على مكتبة ثقيلة نسبياً.
تثبيت الحزم
npm install urql graphql
إعداد Provider وربط العميل
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { createClient, Provider } from 'urql';
const client = createClient({
url: 'https://api.spacex.land/graphql/',
});
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider value={client}>
<App />
</Provider>,
rootElement
);
تنفيذ الاستعلام
على خلاف Apollo، يمكن هنا كتابة الاستعلام مباشرة باستخدام template literal دون الحاجة الإلزامية إلى gql.
import React from "react";
import { useQuery } from 'urql';
const FILMS_QUERY = `
{
launchesPast(limit: 10) {
id
mission_name
}
}
`;
export default function App() {
const [result] = useQuery({
query: FILMS_QUERY,
});
const { data, fetching, error } = result;
if (fetching) return "Loading...";
if (error) return <pre>{error.message}</pre>;
return (
<div>
<h1>SpaceX Launches</h1>
<ul>
{data.launchesPast.map((launch) => (
<li key={launch.id}>{launch.mission_name}</li>
))}
</ul>
</div>
);
}
مميزات urql
- أخف من
Apollo Client. - سهولة في الإعداد والبدء.
- يوفر خطافات مشابهة لما اعتاده مطورو
GraphQLفيReact.
3. الدمج بين React Query وgraphql-request
ليس من الضروري دائماً استخدام عميل GraphQL ضخم. أحياناً يكون الحل الأفضل هو الاعتماد على مكتبة خفيفة مثل graphql-request لتنفيذ الطلبات، مع الاستفادة من قوة React Query في إدارة حالة الخادم والتخزين المؤقت.
هذا الدمج يمنحك توازناً ممتازاً بين البساطة والمرونة.
تثبيت الحزم
npm install react-query graphql-request
إعداد QueryClientProvider
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { QueryClient, QueryClientProvider } from "react-query";
const client = new QueryClient();
const rootElement = document.getElementById("root");
ReactDOM.render(
<QueryClientProvider client={client}>
<App />
</QueryClientProvider>,
rootElement
);
تنفيذ الطلب عبر request() وuseQuery
import React from "react";
import { request, gql } from "graphql-request";
import { useQuery } from "react-query";
const endpoint = "https://api.spacex.land/graphql/";
const FILMS_QUERY = gql`
{
launchesPast(limit: 10) {
id
mission_name
}
}
`;
export default function App() {
const { data, isLoading, error } = useQuery("launches", () => {
return request(endpoint, FILMS_QUERY);
});
if (isLoading) return "Loading...";
if (error) return <pre>{error.message}</pre>;
return (
<div>
<h1>SpaceX Launches</h1>
<ul>
{data.launchesPast.map((launch) => (
<li key={launch.id}>{launch.mission_name}</li>
))}
</ul>
</div>
);
}
لماذا يُعد هذا الخيار عملياً؟
- أقل تعقيداً من مكتبات
GraphQLالكاملة. - يوفر تخزيناً مؤقتاً ممتازاً عبر
React Query. - يسهّل إعادة الجلب
refetchوإبطال الاستعلاماتinvalidate.
4. استخدام React Query مع Axios
إذا كنت تفضّل مكتبات HTTP التقليدية، فيمكنك استخدام Axios لإرسال طلب POST إلى واجهة GraphQL، ثم إدارة الحالة والذاكرة المؤقتة بواسطة React Query.
تثبيت الحزم
npm install react-query axios
تنفيذ استعلام GraphQL عبر Axios
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";
const endpoint = "https://api.spacex.land/graphql/";
const FILMS_QUERY = `
{
launchesPast(limit: 10) {
id
mission_name
}
}
`;
export default function App() {
const { data, isLoading, error } = useQuery("launches", () => {
return axios({
url: endpoint,
method: "POST",
data: { query: FILMS_QUERY }
}).then(response => response.data.data);
});
if (isLoading) return "Loading...";
if (error) return <pre>{error.message}</pre>;
return (
<div>
<h1>SpaceX Launches</h1>
<ul>
{data.launchesPast.map((launch) => (
<li key={launch.id}>{launch.mission_name}</li>
))}
</ul>
</div>
);
}
أهم ما يميز هذا النهج
- مناسب لمن لديهم خبرة مسبقة مع
Axios. - التعامل مع الأخطاء فيه أسهل مقارنة بـ
fetch. - يمكن دمجه بسرعة في المشاريع التي تستخدم
RESTوGraphQLمعاً.
5. استخدام React Query مع fetch API
هذه الطريقة هي الأبسط من حيث الاعتماديات، لأن fetch API متاح افتراضياً في معظم المتصفحات الحديثة. لذلك لن تحتاج إلا إلى تثبيت react-query فقط.
تثبيت الحزمة
npm install react-query
تنفيذ الطلب عبر fetch
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";
const endpoint = "https://api.spacex.land/graphql/";
const FILMS_QUERY = `
{
launchesPast(limit: 10) {
id
mission_name
}
}
`;
export default function App() {
const { data, isLoading, error } = useQuery("launches", () => {
return fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ query: FILMS_QUERY })
})
.then((response) => {
if (response.status >= 400) {
throw new Error("Error fetching data");
} else {
return response.json();
}
})
.then((data) => data.data);
});
if (isLoading) return "Loading...";
if (error) return <pre>{error.message}</pre>;
return (
<div>
<h1>SpaceX Launches</h1>
<ul>
{data.launchesPast.map((launch) => (
<li key={launch.id}>{launch.mission_name}</li>
))}
</ul>
</div>
);
}
ملاحظات مهمة عند استخدام fetch
- يجب تحديد الترويسة
Content-Typeبالقيمةapplication/json. - ينبغي تحويل جسم الطلب إلى نص باستخدام
JSON.stringify(). - مع
fetchيجب معالجة الأخطاء يدوياً، بخلافAxiosالذي يتكفل بجزء من ذلك تلقائياً.
مقارنة سريعة بين الطرق الخمس
| الطريقة | مستوى التعقيد | التخزين المؤقت | الحجم | الحالة المناسبة |
|---|---|---|---|---|
Apollo Client |
مرتفع | متقدم | أكبر | المشاريع الكبيرة والمعقدة |
urql |
متوسط | جيد | أخف | مشاريع GraphQL المرنة |
React Query + graphql-request |
متوسط | ممتاز | خفيف | التوازن بين البساطة والقوة |
React Query + Axios |
منخفض إلى متوسط | ممتاز | متوسط | لمن يستخدم Axios بالفعل |
React Query + fetch |
منخفض | ممتاز | الأخف | المشاريع البسيطة أو الخفيفة |
كيف تختار الطريقة الأنسب لمشروعك؟
- إذا كنت تحتاج منظومة متكاملة لـ
GraphQLفاخترApollo Client. - إذا كنت تريد بديلاً أخف مع تجربة حديثة فاختر
urql. - إذا كنت تبحث عن حل عملي ومرن فالجمع بين
React Queryوgraphql-requestخيار ممتاز. - إذا كان مشروعك يعتمد على
Axiosمسبقاً، فمن المنطقي إعادة استخدامه معReact Query. - إذا أردت أقل عدد ممكن من الاعتماديات، فاستخدم
fetch API.
لماذا تؤثر طريقة جلب البيانات على أداء التطبيق؟
اختيارك للمكتبة أو النهج المناسب لا ينعكس فقط على تجربة المطور، بل يؤثر أيضاً على أداء التطبيق وقابليته للتوسع. فعلى سبيل المثال، توفر آليات cache الجيدة تقليل عدد الطلبات المرسلة إلى الخادم، ما يحسن السرعة ويقلل استهلاك الموارد. كما أن إدارة حالات مثل loading وerror بطريقة سليمة ترفع من جودة تجربة المستخدم النهائية.

الخلاصة التقنية
من الناحية التقنية، لا توجد طريقة واحدة مثالية لكل مشاريع React عند التعامل مع GraphQL API. الاختيار الأفضل يعتمد على حجم التطبيق، وتعقيد البيانات، ومدى حاجتك إلى التخزين المؤقت وإدارة حالة الخادم. إذا كنت تريد حلاً مؤسسياً متكاملاً فـApollo Client يتفوق بوضوح، أما إذا كان هدفك تقليل التعقيد مع الحفاظ على كفاءة عالية، فإن الدمج بين React Query وgraphql-request يُعد من أفضل الخيارات العملية الحديثة.