مكتبة GraphQL للغة Go (Golang) — أداة قوية لإنشاء واجهات API
GraphQL هي لغة استعلام لواجهات API تتيح للعملاء طلب البيانات التي يحتاجونها فقط. في نظام Go (Golang) البيئي، واحدة من أشهر المكتبات للعمل مع GraphQL هي gqlgen (GraphQL Go Generate). تتيح هذه المكتبة إنشاء خوادم GraphQL آمنة من حيث الأنواع مع الحد الأدنى من الكود النمطي. في هذه المقالة، سنشرح بالتفصيل gqlgen، وكيفية تثبيتها، وإعدادها، وأمثلة على استخدامها.
ما هي gqlgen؟
gqlgen هي مولد كود للغة Go يقوم تلقائيًا بإنشاء المحللات (resolvers) والأنواع بناءً على مخطط GraphQL الخاص بك. المزايا الرئيسية:
- أمان الأنواع — يتم التحقق من جميع الأنواع في مرحلة التجميع
- الحد الأدنى من الكود النمطي — تقوم المكتبة بتوليد معظم الكود نيابة عنك
- المرونة — دعم الاشتراكات والتحويرات والاستعلامات المعقدة
- الأداء — سرعة عالية في العمل، وهي سمة مميزة للغة Go
تثبيت gqlgen
للبدء، قم بتثبيت المكتبة وأداة سطر الأوامر:
go get github.com/99designs/gqlgengo run github.com/99designs/gqlgen initسيقوم الأمر init بإنشاء هيكل أساسي للمشروع مع الملفات schema.graphqls و gqlgen.yml والكود المُولَّد.
هيكل المشروع
بعد التهيئة، ستحصل على الهيكل التالي:
my-graphql-app/├── gqlgen.yml # إعدادات المولد├── graph/│ ├── schema.graphqls # مخطط GraphQL│ ├── resolver.go # المحللات (الكود الخاص بك)│ └── models_gen.go # النماذج المُولَّدة (لا تقم بتحريرها)├── server.go # نقطة الدخول└── go.modكتابة مخطط GraphQL
مثال على ملف schema.graphqls لمدونة بسيطة:
type Query { posts: [Post!]! post(id: ID!): Post}
type Mutation { createPost(input: PostInput!): Post! deletePost(id: ID!): Boolean!}
type Post { id: ID! title: String! content: String! author: String! createdAt: Time!}
input PostInput { title: String! content: String! author: String!}
scalar Timeتوليد الكود
بعد وصف المخطط، قم بتنفيذ:
go run github.com/99designs/gqlgen generateسيؤدي ذلك إلى إنشاء الملفات models_gen.go و generated.go مع الأنواع وواجهات المحللات.
تنفيذ المحللات
الآن تحتاج إلى تنفيذ المنطق في resolver.go:
package graph
import ( "context" "time")
// نموذج البياناتtype Post struct { ID string `json:"id"` Title string `json:"title"` Content string `json:"content"` Author string `json:"author"` CreatedAt time.Time `json:"createdAt"`}
// مخزن في الذاكرةvar posts = []*Post{ { ID: "1", Title: "مقدمة في GraphQL", Content: "GraphQL هي لغة استعلام...", Author: "إيفان بيتروف", CreatedAt: time.Now(), },}
// محلل لـ Query.postsfunc (r *queryResolver) Posts(ctx context.Context) ([]*Post, error) { return posts, nil}
// محلل لـ Query.postfunc (r *queryResolver) Post(ctx context.Context, id string) (*Post, error) { for _, post := range posts { if post.ID == id { return post, nil } } return nil, nil}
// محلل لـ Mutation.createPostfunc (r *mutationResolver) CreatePost(ctx context.Context, input PostInput) (*Post, error) { newPost := &Post{ ID: fmt.Sprintf("%d", len(posts)+1), Title: input.Title, Content: input.Content, Author: input.Author, CreatedAt: time.Now(), } posts = append(posts, newPost)