مقدمة إلى GraphQL و Go
GraphQL هي لغة استعلام لواجهات برمجة التطبيقات (API) تتيح للعملاء الحصول على البيانات التي يحتاجونها بالضبط، دون أي شيء إضافي. على عكس REST، حيث يعيد كل نقطة نهاية بنية بيانات ثابتة، تمنح GraphQL المرونة والتحكم. وبالاقتران مع Go (Golang) - وهي لغة سريعة وآمنة من حيث الأنواع وبسيطة - تحصل على أداة قوية لإنشاء خدمات ويب حديثة.
في هذا الدليل، سننشئ واجهة برمجة تطبيقات GraphQL بسيطة بلغة Go من الصفر. ستتعلم كيفية تثبيت التبعيات، ووصف المخطط، وتنفيذ المحللات، وتشغيل الخادم. المقالة موجهة للمبتدئين، لذا تم شرح جميع الخطوات بالتفصيل.
1. إعداد المشروع وتثبيت التبعيات
قبل كتابة الكود، تأكد من تثبيت Go الإصدار 1.18 أو أعلى. أنشئ دليلاً جديداً للمشروع وقم بتهيئة الوحدة النمطية:
mkdir graphql-go-tutorialcd graphql-go-tutorialgo mod init graphql-go-tutorialاختيار المكتبة: gqlgen
هناك عدة مكتبات للعمل مع GraphQL في Go. سنستخدم gqlgen - وهو مولد كود شائع يقوم بإنشاء الأنواع والمحللات بناءً على المخطط. قم بتثبيته:
go get github.com/99designs/gqlgen@latestتهيئة gqlgen
نفذ الأمر لإنشاء الملفات الافتراضية:
go run github.com/99designs/gqlgen initسينشئ هذا الأمر عدة ملفات:
graph/schema.graphqls- ملف مخطط GraphQL؛graph/resolver.go- مسودة المحللات؛server.go- نقطة دخول الخادم؛gqlgen.yml- إعدادات التوليد.
2. وصف مخطط GraphQL
افتح ملف graph/schema.graphqls. بشكل افتراضي، يوجد فيه مثال مع نوع Todo. سنقوم بتوسيعه بإضافة نوع User وبعض الاستعلامات.
استبدل محتوى الملف بما يلي:
type User { id: ID! name: String! email: String!}
type Todo { id: ID! text: String! done: Boolean! user: User!}
type Query { todos: [Todo!]! users: [User!]! user(id: ID!): User}
type Mutation { createTodo(text: String!, userId: ID!): Todo! markDone(id: ID!): Todo!}هنا قمنا بتعريف:
- User - مستخدم مع الحقول id, name, email.
- Todo - مهمة مع الحقول id, text, done ومرجع للمستخدم.
- Query - نقاط دخول لقراءة البيانات.
- Mutation - عمليات لتعديل البيانات.
3. توليد الكود وتنفيذ المحللات
بعد وصف المخطط، يجب توليد كود Go. نفذ:
go run github.com/99designs/gqlgen generateسينشئ هذا الملفات models_gen.go ويحدث resolver.go. الآن افتح graph/resolver.go.
إضافة مخزن البيانات
للبساطة، سنخزن البيانات في الذاكرة. أضف الهيكل في resolver.go:
type Resolver struct { Users []*model.User Todos []*model.Todo}لا تنس استيراد الحزمة model.
تنفيذ الاستعلامات (Query)
ابحث عن الطرق المولدة لـ Query. سنقوم بتنفيذها:
func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { return r.Resolver.Todos, nil}
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) { return r.Resolver.Users, nil}
func (r *queryResolver) User(ctx context.Context, id string) (*model.User, error) { for _, u := range r.Resolver.Users { if u.ID == id { return u, nil } } return nil, fmt.Errorf("user not found")}
المدونات
توصيات الكتب
اقرأ أيضًا