مقارنة GraphQL و REST في C#: أيهما تختار لـ API الخاص بك في 2024

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

GraphQL vs REST في C#: معركة العمالقة أم اختيار الأداة المناسبة للمهمة؟

\n\n

مرحبًا أيها الزملاء! إذا كنت تكتب بلغة C# وتنشئ واجهات API، فمن المؤكد أن سؤال "REST أم GraphQL؟" قد طرأ على ذهنك أكثر من مرة. إنه مثل الجدل حول أيهما أفضل: المطرقة أم مفك البراغي الكهربائي. كلاهما أدوات، لكن لمهام مختلفة. في هذه المقالة، لن نتعصب لصالح تقنية معينة، بل سنناقش بواقعية، مع أمثلة كود بلغة C#، متى يكون GraphQL هو الخيار الرابح، ومتى يبقى REST القديم الجيد هو الملك.

\n\n

نحن فريق PythonLib، ورغم أن الاسم يحمل "Python"، إلا أننا نحب نظام .NET و C#. اليوم سنلقي نظرة على عالم واجهات API بلغة C# ونتعرف على كيفية اتخاذ القرار الصحيح. هيا بنا!

\n\n

شرح مبسط: REST و GraphQL لمطور C#

\n\n

REST (Representational State Transfer) هو أسلوب معماري نعرفه جميعًا ونحبه. في C#، على الأرجح تستخدم ASP.NET Core Web API. تقوم بإنشاء وحدات تحكم (Controllers) ونقاط نهاية (Endpoints)، وكل نقطة نهاية تعيد بنية بيانات ثابتة. تريد الحصول على مستخدم؟ تذهب إلى /api/users/1. تريد طلباته؟ تذهب إلى /api/users/1/orders. بسيط، يمكن التنبؤ به، لكنه غالبًا ما يؤدي إلى استقبال بيانات زائدة (over-fetching) أو الحاجة إلى عدة طلبات (under-fetching).

\n\n

GraphQL هي لغة استعلام طورتها فيسبوك. في عالم C#، يتم تنفيذها عبر مكتبات مثل Hot Chocolate (الأكثر شيوعًا) أو GraphQL.NET. لديك نقطة نهاية واحدة (عادةً /graphql)، ويقرر العميل الحقول التي يحتاجها. تريد اسم المستخدم وأول طلب فقط؟ تفضل! لا مزيد من البيانات الزائدة.

\n\n

مقارنة عملية: كود C#

\n\n

دعنا ننتقل من النظرية إلى التطبيق. لنفترض أن لدينا نموذجًا بسيطًا: User و Order.

\n\n
// نماذج البيانات\npublic class User\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public string Email { get; set; }\n    public string Phone { get; set; }\n    public List<Order> Orders { get; set; }\n}\n\npublic class Order\n{\n    public int Id { get; set; }\n    public string ProductName { get; set; }\n    public decimal Price { get; set; }\n    public DateTime CreatedAt { get; set; }\n}\n
\n\n

مثال على REST API باستخدام ASP.NET Core

\n\n
[ApiController]\n[Route("api/[controller]")]\npublic class UsersController : ControllerBase\n{\n    [HttpGet("{id}")]\n    public async Task<ActionResult<User>> GetUser(int id)\n    {\n        // لنفترض أن البيانات تأتي من قاعدة البيانات\n        var user = await _dbContext.Users.FindAsync(id);\n        if (user == null) return NotFound();\n        return Ok(user); // يعيد جميع الحقول: Id, Name, Email, Phone, Orders\n    }\n}\n
\n\n

المشكلة؟ إذا كان العميل يحتاج فقط الاسم والبريد الإلكتروني، فسيظل يتلقى Phone و Orders. وإذا كان بحاجة إلى الطلبات، فعليه إجراء طلب منفصل إلى /api/users/1/orders.

\n\n

مثال على GraphQL API باستخدام Hot Chocolate

\n\n
public class Query\n{\n    public async Task<User> GetUser(int id, [Service] AppDbContext dbContext)\n    {\n        return await dbContext.Users.FindAsync(id);\n    }\n}\n\n// التسجيل في Program.cs\nbuilder.Services\n    .AddGraphQLServer()\n    .AddQueryType<Query>();\n
\n\n

الآن يمكن للعميل طلب ما يحتاجه بالضبط:

\n\n
// استعلام GraphQL\n{\n  user(id: 1) {\n    name\n    email\n    orders {\n      productName\n      price\n    }\n  }\n}\n
\n\n

سيحتوي الرد فقط على name و email ومصفوفة orders مع الحقول productName و price. لا بيانات زائدة. رائع!

\n\n

متى يفوز REST في C# (وهذا طبيعي)

\n\n

1. البساطة والتخزين المؤقت. يمكن تخزين REST API مؤقتًا بسهولة على مستوى HTTP (CDN، بروكسي). يمكن تخزين طلب GET على /api/products مؤقتًا، وهذا يفيد الجميع.

المدونات

توصيات الكتب