GraphQL API مع Go: دليل تعليمي خطوة بخطوة عملي

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

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

ابدأ الدورة

مقدمة: لماذا يعتبر GraphQL و Go ثنائياً مثالياً

\n

في تطوير الويب الحديث، أصبح GraphQL معياراً لإنشاء واجهات برمجة تطبيقات (API) مرنة وفعالة. وبالاقتران مع لغة Go (Golang)، المعروفة بأدائها العالي وبساطتها، تحصل على أداة قوية لتطوير الواجهة الخلفية (backend). في هذا الدليل التعليمي خطوة بخطوة، سنقوم بإنشاء GraphQL API كامل بلغة Go من الصفر، باستخدام المكتبة الشهيرة gqlgen.

\n

ستتعلم كيفية إعداد المشروع، وتحديد المخطط (schema)، وتنفيذ المحللّات (resolvers)، وإضافة middleware للمصادقة. في نهاية المقال، سيكون لديك API يعمل وجاهز للتكامل مع أي واجهة أمامية (frontend).

\n\n

1. إعداد المشروع وتثبيت التبعيات

\n

أولاً، سنقوم بإنشاء وحدة Go جديدة وتثبيت الحزم اللازمة. تأكد من تثبيت Go الإصدار 1.18 أو أعلى.

\n
mkdir graphql-go-tutorial\ncd graphql-go-tutorial\ngo mod init graphql-go-tutorial\ngo get github.com/99designs/gqlgen@latest\ngo get github.com/99designs/gqlgen/graphql/introspection@latest
\n

الآن، سنقوم بتهيئة gqlgen في المشروع. هذا الأمر سينشئ هيكل الملفات الأساسي:

\n
go run github.com/99designs/gqlgen init
\n

بعد التنفيذ، سترى الهيكل التالي:

\n
    \n
  • graph/ — دليل يحتوي على ملفات المخطط والمحللّات
  • \n
  • graph/schema.graphqls — تعريف مخطط GraphQL
  • \n
  • graph/resolver.go — نماذج أولية للمحللّات
  • \n
  • server.go — نقطة الدخول للتطبيق
  • \n
  • gqlgen.yml — إعدادات المولّد (generator)
  • \n
\n\n

2. تعريف مخطط GraphQL

\n

افتح ملف graph/schema.graphqls وحدد نموذج البيانات الخاص بنا. على سبيل المثال، سننشئ نظاماً بسيطاً لإدارة المهام (Task Manager):

\n
type Task {\n  id: ID!\n  title: String!\n  description: String\n  status: TaskStatus!\n  createdAt: Time!\n}\n\nenum TaskStatus {\n  TODO\n  IN_PROGRESS\n  DONE\n}\n\ntype Query {\n  tasks(status: TaskStatus): [Task!]!\n  task(id: ID!): Task\n}\n\ntype Mutation {\n  createTask(title: String!, description: String): Task!\n  updateTask(id: ID!, title: String, description: String, status: TaskStatus): Task!\n  deleteTask(id: ID!): Boolean!\n}\n\nscalar Time
\n

بعد حفظ المخطط، قم بتشغيل توليد الكود:

\n
go run github.com/99designs/gqlgen generate
\n

سينشئ هذا الأمر ملف graph/model/models_gen.go مع هياكل Go وسيُحدّث المحللّات.

\n\n

3. تنفيذ المحللّات ومنطق الأعمال

\n

الآن، سنقوم بتنفيذ المنطق في ملف graph/schema.resolvers.go. أولاً، سننشئ مخزناً بسيطاً في الذاكرة (in-memory store):

\n
// في graph/resolver.go سنضيف المخزن\ntype Resolver struct {\n  tasks []*model.Task\n  mu    sync.Mutex\n}\n\nfunc NewResolver() *Resolver {\n  return &Resolver{\n    tasks: make([]*model.Task, 0),\n  }\n}
\n

الآن، سنقوم بتنفيذ المحللّات لـ Query و Mutation:

\n
// Query.Task\nfunc (r *queryResolver) Task(ctx context.Context, id string) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  for _, task := range r.tasks {\n    if task.ID == id {\n      return task, nil\n    }\n  }\n  return nil, fmt.Errorf("task not found")\n}\n\n// Mutation.CreateTask\nfunc (r *mutationResolver) CreateTask(ctx context.Context, title string, description *string) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  task := &model.Task{\n    ID:          uuid.New().String(),\n    Title:       title,\n    Description: description,\n    Status:      model.TaskStatusTodo,\n    CreatedAt:   time.Now(),\n  }\n  \n  r.tasks = append(r.tasks, task)\n  return task, nil\n}\n\n// Mutation.UpdateTask\nfunc (r *mutationResolver) UpdateTask(ctx context.Context, id string, title *string, description *string, status *model.TaskStatus) (*model.Task, error) {\n  r.mu.Lock()\n  defer r.mu.Unlock()\n  \n  for _, task                

المدونات

توصيات الكتب