GraphQL API مع C#: دليل تعليمي عملي خطوة بخطوة
في تطوير الويب الحديث، أصبح GraphQL بديلاً شائعًا بشكل متزايد لـ REST API. على عكس REST، حيث يعيد كل نقطة نهاية بنية بيانات ثابتة، يسمح GraphQL للعميل بطلب البيانات التي يحتاجها بالضبط. في هذا الدليل التعليمي، سننشئ GraphQL API كاملًا باستخدام C# (.NET) مع مكتبة Hot Chocolate. ستتعلم كيفية إعداد الخادم، تعريف أنواع البيانات، تنفيذ الاستعلامات والطفرات، بالإضافة إلى إضافة الاشتراكات للتحديثات في الوقت الفعلي.
ما هو GraphQL ولماذا يجب استخدامه مع C#؟
GraphQL هي لغة استعلام لواجهات API، طورتها Facebook. المزايا الرئيسية:
- مرونة الاستعلامات — يقرر العميل بنفسه الحقول التي سيحصل عليها
- نقطة دخول موحدة — نقطة نهاية واحدة لجميع الاستعلامات
- كتابة قوية — جميع أنواع البيانات محددة بدقة
- عدم وجود over-fetching و under-fetching — تحصل بالضبط على ما طلبت
في نظام .NET البيئي، أفضل مكتبة لتنفيذ GraphQL هي Hot Chocolate. وهي تدعم جميع إمكانيات مواصفات GraphQL، بما في ذلك الاستعلامات (queries) والطفرات (mutations) والاشتراكات (subscriptions).
إعداد المشروع وتثبيت التبعيات
لنبدأ بإنشاء مشروع ASP.NET Core جديد. افتح الطرفية أو سطر الأوامر ونفذ:
dotnet new webapi -n GraphQLDemocd GraphQLDemoالآن سنقوم بتثبيت حزمة Hot Chocolate:
dotnet add package HotChocolate.AspNetCoredotnet add package HotChocolate.AspNetCore.Playgroundلننشئ نموذج بيانات لواجهة API الخاصة بنا. لنفترض أننا سنعمل مع الكتب والمؤلفين. أنشئ مجلد Models وأضف إليه الفئات:
// Models/Author.cspublic class Author{ public int Id { get; set; } public string Name { get; set; } public ICollection<Book> Books { get; set; }}
// Models/Book.cspublic class Book{ public int Id { get; set; } public string Title { get; set; } public int AuthorId { get; set; } public Author Author { get; set; }}إنشاء مخطط GraphQL والمحللين (Resolvers)
في GraphQL، المكونات الرئيسية هي الأنواع والاستعلامات (Query) والطفرات (Mutation). لننشئ مجلد GraphQL ونضيف إليه الملفات:
// GraphQL/Query.cspublic class Query{ public IQueryable<Book> GetBooks([Service] ApplicationDbContext context) { return context.Books.Include(b => b.Author); }
public Book GetBook(int id, [Service] ApplicationDbContext context) { return context.Books.Include(b => b.Author).FirstOrDefault(b => b.Id == id); }
public IQueryable<Author> GetAuthors([Service] ApplicationDbContext context) { return context.Authors.Include(a => a.Books); }}
// GraphQL/Mutation.cspublic class Mutation{ public async Task<Book> AddBook(string title, int authorId, [Service] ApplicationDbContext context) { var book = new Book { Title = title, AuthorId = authorId }; context.Books.Add(book); await context.SaveChangesAsync(); return book; }
public async Task<Author> AddAuthor(string name, [Service] ApplicationDbContext context) { var author = new Author { Name = name }; context.Authors.Add(author); await context.SaveChangesAsync(); return author; }}الآن سنقوم بتسجيل هذه الفئات في Program.cs:
// Program.csvar builder = WebApplication.CreateBuilder(args);
builder.Services .AddDbContext<ApplicationDbContext>(options => options.U