أساسيات Apollo Client
البدء مع Apollo Client
Apollo Client هو مكتبة شاملة لإدارة الحالة لـ JavaScript تمكنك من إدارة البيانات المحلية والبعيدة باستخدام GraphQL. إنه عميل GraphQL الأكثر شيوعًا لتطبيقات React وVue وAngular وJavaScript الفانيليا.
ما هو Apollo Client؟
يوفر Apollo Client التخزين المؤقت الذكي وجلب البيانات التصريحي وأدوات تطوير قوية. يتعامل مع طلبات الشبكة والتخزين المؤقت ومعالجة الأخطاء وتحديثات واجهة المستخدم المتفائلة تلقائيًا.
- InMemoryCache: التخزين المؤقت المطبّع لتخزين البيانات بكفاءة
- جلب البيانات التصريحي: خطافات React مثل useQuery وuseMutation
- التحديثات التلقائية: تحديثات واجهة المستخدم عند تغيير ذاكرة التخزين المؤقت
- معالجة الأخطاء: حالات أخطاء مدمجة ومنطق إعادة المحاولة
- أدوات التطوير: امتداد المتصفح لتصحيح الاستعلامات وذاكرة التخزين المؤقت
- دعم TypeScript: أمان كامل للنوع مع أنواع مُنشأة
التثبيت والإعداد
# تثبيت Apollo Client وGraphQL npm install @apollo/client graphql # لتطبيقات React npm install @apollo/client graphql react
إنشاء مثيل Apollo Client
قم بإعداد Apollo Client مع نقطة نهاية GraphQL وتكوين ذاكرة التخزين المؤقت.
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';
const client = new ApolloClient({
uri: 'https://api.example.com/graphql',
cache: new InMemoryCache()
});
export default client;
import {
ApolloClient,
InMemoryCache,
HttpLink,
ApolloLink
} from '@apollo/client';
// اتصال HTTP بواجهة برمجة التطبيقات
const httpLink = new HttpLink({
uri: 'https://api.example.com/graphql'
});
// وسيط لإضافة رمز المصادقة إلى الرؤوس
const authLink = new ApolloLink((operation, forward) => {
const token = localStorage.getItem('auth_token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
});
return forward(operation);
});
// إنشاء عميل مع المصادقة وذاكرة التخزين المؤقت
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-and-network'
}
}
});
export default client;
ApolloProvider - توفير العميل لـ React
قم بتغليف تطبيق React الخاص بك بـ ApolloProvider لجعل العميل متاحًا في جميع أنحاء شجرة المكونات.
import React from 'react';
import { ApolloProvider } from '@apollo/client';
import client from './apollo-client';
import UserList from './components/UserList';
function App() {
return (
<ApolloProvider client={client}>
<div className="App">
<h1>تطبيق GraphQL الخاص بي</h1>
<UserList />
</div>
</ApolloProvider>
);
}
export default App;
خطاف useQuery - جلب البيانات
ينفذ خطاف useQuery استعلامات GraphQL ويعيد حالات التحميل والخطأ والبيانات.
import React from 'react';
import { useQuery, gql } from '@apollo/client';
const GET_USERS = gql`
query GetUsers {
users {
id
name
email
avatar
}
}
`;
function UserList() {
const { loading, error, data } = useQuery(GET_USERS);
if (loading) return <p>جارٍ تحميل المستخدمين...</p>;
if (error) return <p>خطأ: {error.message}</p>;
return (
<div>
<h2>المستخدمون</h2>
<ul>
{data.users.map(user => (
<li key={user.id}>
<img src={user.avatar} alt={user.name} />
<strong>{user.name}</strong> - {user.email}
</li>
))}
</ul>
</div>
);
}
export default UserList;
متغيرات الاستعلام
مرر متغيرات ديناميكية إلى استعلاماتك للتصفية والمعلمات.
import React from 'react';
import { useQuery, gql } from '@apollo/client';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
id
title
}
}
}
`;
function UserProfile({ userId }) {
const { loading, error, data } = useQuery(GET_USER, {
variables: { id: userId }
});
if (loading) return <p>جارٍ التحميل...</p>;
if (error) return <p>خطأ: {error.message}</p>;
const { user } = data;
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
<h3>المنشورات</h3>
<ul>
{user.posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
export default UserProfile;
إعادة الجلب والاستطلاع
أعد جلب الاستعلامات يدويًا أو قم بإعداد استطلاع تلقائي للتحديثات في الوقت الفعلي.
import React from 'react';
import { useQuery, gql } from '@apollo/client';
const GET_STATS = gql`
query GetStats {
stats {
users
posts
comments
lastUpdated
}
}
`;
function Dashboard() {
const { loading, error, data, refetch } = useQuery(GET_STATS, {
pollInterval: 5000 // الاستطلاع كل 5 ثوانٍ
});
if (loading) return <p>جارٍ تحميل الإحصائيات...</p>;
if (error) return <p>خطأ: {error.message}</p>;
return (
<div>
<h2>لوحة المعلومات</h2>
<div>المستخدمون: {data.stats.users}</div>
<div>المنشورات: {data.stats.posts}</div>
<div>التعليقات: {data.stats.comments}</div>
<div>آخر تحديث: {data.stats.lastUpdated}</div>
<button onClick={() => refetch()}>
تحديث الإحصائيات
</button>
</div>
);
}
export default Dashboard;
سياسات جلب الشبكة
يوفر Apollo Client سياسات جلب مختلفة للتحكم في كيفية جلب البيانات وتخزينها مؤقتًا.
// cache-first (افتراضي): التحقق من ذاكرة التخزين المؤقت أولاً، الجلب إذا لم يتم العثور عليه
const { data } = useQuery(QUERY, {
fetchPolicy: 'cache-first'
});
// cache-and-network: إرجاع البيانات المخزنة مؤقتًا، ثم الجلب من الشبكة
const { data } = useQuery(QUERY, {
fetchPolicy: 'cache-and-network'
});
// network-only: الجلب دائمًا من الشبكة، تحديث ذاكرة التخزين المؤقت
const { data } = useQuery(QUERY, {
fetchPolicy: 'network-only'
});
// no-cache: الجلب دائمًا، لا تخزين النتيجة مؤقتًا
const { data } = useQuery(QUERY, {
fetchPolicy: 'no-cache'
});
// cache-only: إرجاع البيانات المخزنة مؤقتًا فقط، عدم الجلب أبدًا
const { data } = useQuery(QUERY, {
fetchPolicy: 'cache-only'
});
- استخدم
cache-firstللبيانات الثابتة التي نادرًا ما تتغير - استخدم
cache-and-networkللبيانات التي تتحدث بشكل متكرر - استخدم
network-onlyللمصادقة أو البيانات الحرجة في الوقت الفعلي - استخدم
no-cacheللبيانات الحساسة التي لا ينبغي تخزينها مؤقتًا
معالجة الأخطاء
import React from 'react';
import { useQuery, gql } from '@apollo/client';
const GET_POSTS = gql`
query GetPosts {
posts {
id
title
}
}
`;
function Posts() {
const { loading, error, data } = useQuery(GET_POSTS, {
onError: (error) => {
console.error('خطأ في الاستعلام:', error);
// تسجيل في خدمة تتبع الأخطاء
},
onCompleted: (data) => {
console.log('اكتمل الاستعلام:', data);
}
});
if (loading) return <p>جارٍ التحميل...</p>;
if (error) {
// خطأ في الشبكة
if (error.networkError) {
return <p>خطأ في الشبكة. يرجى التحقق من اتصالك.</p>;
}
// أخطاء GraphQL
if (error.graphQLErrors.length > 0) {
return (
<div>
{error.graphQLErrors.map((err, i) => (
<p key={i}>خطأ: {err.message}</p>
))}
</div>
);
}
return <p>حدث خطأ ما.</p>;
}
return (
<ul>
{data.posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
export default Posts;
- قم بإعداد Apollo Client في تطبيق React مع رؤوس المصادقة
- أنشئ مكونًا يجلب قائمة بمنشورات المدونة باستخدام useQuery
- أضف زر إعادة جلب يحدث البيانات يدويًا
- نفذ حالات تحميل وخطأ مناسبة مع رسائل سهلة الاستخدام
- جرب سياسات جلب مختلفة (cache-first، cache-and-network، network-only) ولاحظ السلوك