مقدمة: API ليس مجرد طلبات، بل حوار
منذ زمن بعيد، في عصر التطبيقات المتجانسة، كان المطورون يكتبون الواجهة الخلفية بلغة PHP أو Java، بينما كانت الواجهة الأمامية تستدعي ببساطة عناوين URL جاهزة. كان كل شيء بسيطًا، لكنه بطيء. اليوم، يفرض نظام TypeScript البيئي قواعد جديدة: نحن لا نريد فقط تبادل البيانات، بل نريد القيام بذلك بأمان، وبشكل صارم، ومع الإكمال التلقائي. وهنا يأتي دور العمالقة الثلاثة: REST وGraphQL وgRPC.
في هذه المقالة، لن نعيد سرد الوثائق. سنستعرض كل بروتوكول من وجهة نظر ممارس يستخدم TypeScript: سنرى أمثلة كود حقيقية، ونقارن الأداء، ونفهم أي أداة مناسبة لمشروعك. إذا كنت تكتب بلغة TypeScript وتريد تطوير مهاراتك في العمل مع API، فأنت في المكان الصحيح.
REST API على TypeScript: الكلاسيكية التي لا تموت
REST (نقل الحالة التمثيلية) هو المعيار الفعلي. البساطة، طرق HTTP (GET وPOST وPUT وDELETE) والموارد. لكن في TypeScript، يتجلى REST بشكل جديد: نحصل على كتابة أنواع صارمة للطلبات والاستجابات.
كيف يبدو عميل REST مكتوب الأنواع
لنكتب عميلًا بسيطًا ولكنه عملي لـ REST API على TypeScript. بدون مكتبات إضافية — فقط fetch والأنواع.
// أنواع للاستجابةinterface User { id: number; name: string; email: string;}
interface ApiResponse<T> { data: T; status: number; message: string;}
// عميل مكتوب الأنواعclass RestClient { private baseUrl: string;
constructor(baseUrl: string) { this.baseUrl = baseUrl; }
async get<T>(endpoint: string): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Success', }; }
async post<T, U>(endpoint: string, body: U): Promise<ApiResponse<T>> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), });
if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data: T = await response.json(); return { data, status: response.status, message: 'Created', }; }}
// الاستخدامconst client = new RestClient('https://jsonplaceholder.typicode.com');
async function fetchUser() { const response = await client.get<User>('/users/1'); console.log(response.data.name); // الإكمال التلقائي يعمل!}
fetchUser();كما ترون، REST API TypeScript يمنحنا التحكم في الأنواع في كل مرحلة. خطأ في اسم الحقل؟ سيكتشفه TypeScript في مرحلة التجميع.
متى تختار REST
- البساطة — REST سهل الفهم والصيانة.
- التخزين المؤقت — التخزين المؤقت لـ HTTP يعمل مباشرة.
- تطبيقات CRUD — المدونات، المتاجر، لوحات التحكم.
العيب: في الاستعلامات المتداخلة المعقدة، إما تحصل على الكثير من البيانات (over-fetching) أو تقوم بـ N من الطلبات (مشكلة N+1).
GraphQL على TypeScript: المرونة والدقة
GraphQL هي لغة استعلام أنشأتها Facebook. ميزتها الرئيسية: أنت من تقرر أي الحقول تحصل عليها. GraphQL TypeScript هو ثنائي قوي يوفر أمانًا كاملاً للأنواع على العميل والخادم.
كتابة استعلام GraphQL مع كتابة الأنواع
كمثال، سنستخدم مكتبة graphql-request — عميل خفيف لـ TypeScript.
import { request, gql } from 'grap