How-To Guides

بناء واجهات برمجة تطبيقات REST قابلة للتوسع باستخدام Go: دليل للمطورين

المقدمة

أصبحت لغة Go، المعروفة أيضاً باسم Golang، خياراً مفضلاً بسرعة لبناء خدمات الخلفية عالية الأداء. يجعل نموذج التزامن فيها، والكتابة الثابتة، وسرعة التنفيذ الاستثنائية منها مرشحاً مثالياً لهندسة المعمارية الحديثة للخدمات المصغرة. بينما توفر أطر عمل مثل Gin أو Echo راحةً كبيرة، فإن فهم كيفية بناء واجهات برمجة تطبيقات REST باستخدام المكتبة القياسية للغة Go أمر بالغ الأهمية لإتقان الآليات الأساسية للغة. يأخذك هذا الدليل عبر إنشاء واجهة برمجة تطبيقات REST أساسية وعملية باستخدام المكتبة القياسية فقط، مما يوفر أساساً متيناً قبل الانتقال إلى الأدوات الخارجية.

إعداد هيكل المشروع

قبل كتابة الكود، قم بتهيئة وحدة Go الخاصة بك. افتح طرفية الأوامر (Terminal) وقم بتشغيل الأمر التالي في دليل المشروع الخاص بك:

go mod init my-rest-api

ينشئ هذا الأمر ملف go.mod، الذي يدير تبعيات مشروعك. في هذا البرنامج التعليمي، سنعتمد كلياً على الحزم المدمجة في Go وهي net/http و encoding/json.

تعريف هياكل البيانات

لنبدأ بتعريف مورد بسيط: "مهمة" (Task). سنستخدم بنية هيكلية (struct) لتمثيل هذا البيانات. تعتبر وسوم `json` ضرورية لتحويل البيانات (marshaling) وعكسها (unmarshaling) من وإلى طلبات واستجابات HTTP.

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Task struct {
    ID     string `json:"id"`
    Title  string `json:"title"`
    Done   bool   `json:"done"`
}

تنفيذ معالجات HTTP

تستخدم حزمة net/http في Go واجهة HandlerFunc. المعالج هو ببساطة دالة ذات التوقيع func(http.ResponseWriter, *http.Request). دعنا ننفذ معالجاَ لعرض جميع المهام ومعالجاَ آخر لإنشاء مهمة جديدة.

معالج القائمة

يقرأ هذا المعالج شريحة (slice) عالمية من المهام ويحولها إلى استجابة JSON. من المهم تعيين رأس Content-Type بشكل صحيح حتى يعرف العملاء كيفية تفسير الحمولة (payload).

var tasks []Task

func listTasks(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(tasks)
}

معالج الإنشاء

يستمع هذا المعالج لطلبات POST. يقوم بفك تشفير جسم الطلب JSON الوارد إلى بنية هيكلية جديدة Task، ويضيفها إلى شريحتنا، ويعيد الكائن المنشور مع رمز حالة 201 Created.

func createTask(w http.ResponseWriter, r *http.Request) {
    var newTask Task
    // فك تشفير جسم JSON من الطلب
    err := json.NewDecoder(r.Body).Decode(&newTask)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // أضف منطق المعرف هنا (على سبيل المثال، باستخدام حزمة uuid)
    newTask.ID = "1" 
    tasks = append(tasks, newTask)

    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(newTask)
}

التوجيه وإعداد الخادم

الآن بعد أن تم تعريف معالجاتنا، نحتاج إلى ربطها بمسارات عناوين URL محددة. في Go، نستخدم http.HandleFunc أو http.NewServeMux للتوجيه الأكثر تعقيداً.

func main() {
    // تهيئة شريحة المهام
    tasks = []Task{
        {ID: "1", Title: "تعلم Go", Done: false},
    }

    // تسجيل المسارات
    http.HandleFunc("/tasks", listTasks)
    http.HandleFunc("/tasks/create", createTask)

    // بدء الخادم على المنفذ 8080
    log.Println("Server starting on :8080")
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

الخاتمة

إن بناء واجهات برمجة تطبيقات REST باستخدام المكتبة القياسية لـ Go أمر مباشر وقوي. من خلال الاستفادة من net/http و encoding/json، تحصل على تحكم دقيق في خادمك دون الحمل الإضافي لأطر العمل الكبيرة. بينما هذا المثال أساسي، فإنه يوضح المفاهيم الأساسية مثل تحويل البيانات إلى JSON، وأكواد الحالة، ومعالجة الطلبات التي تنطبق على أي تطبيق ويب مكتوب بلغة Go. بالنسبة للتطبيقات الإنتاجية، فكر في إضافة برمجيات وسيطة (middleware) للسجل، والمصادقة، وCORS، أو الانتقال إلى موجه مثل Chi أو Gin لاحتياجات التوجيه الأكثر تعقيداً. سعيد بالبرمجة!

Share: