كيفية كتابة REST API على Go في 30 دقيقة: عمليًا

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

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

ابدأ الدورة

مقدمة: لماذا Go هو الخيار الأمثل لـ REST API

Go (Golang) هي لغة برمجة مُجمَّعة، تم إنشاؤها في Google للأنظمة عالية التحميل. إنها تجمع بين سرعة C، وبساطة Python، والدعم المدمج للتوازي. لإنشاء REST API، تقدم Go مكتبة قياسية قوية net/http وأطر عمل شائعة مثل gorilla/mux و gin.

في هذا الدليل، سنقوم خلال 30 دقيقة بإنشاء REST API كامل لإدارة قائمة المهام (Todo List) باستخدام Go الخالص دون أطر عمل خارجية. ستتعلم:

  • إعداد التوجيه والمعالجات
  • العمل مع JSON (التسلسل / إلغاء التسلسل)
  • تنفيذ عمليات CRUD (إنشاء، قراءة، تحديث، حذف)
  • إضافة middleware للتسجيل و CORS

سيتم كتابة كل الكود في ملف واحد main.go للتبسيط. هيا بنا!



الخطوة 1: الهيكل الأساسي وتشغيل خادم HTTP

أنشئ ملفًا باسم main.go وأضف الكود التالي. سنعلن عن هيكل بيانات للمهمة ونشغل خادمًا بسيطًا.

package main

import ( "encoding/json" "log" "net/http" "strconv" "strings" "sync" "time")

// Task — هيكل المهمةtype Task struct { ID int `json:"id"` Title string `json:"title"` Completed bool `json:"completed"` CreatedAt time.Time `json:"created_at"`}

// مخزن المهام (في الذاكرة)var ( tasks = make(map[int]Task) nextID = 1 mu sync.Mutex)

func main() { // المسارات http.HandleFunc("/api/tasks", tasksHandler) http.HandleFunc("/api/tasks/", taskByIDHandler)

log.Println("الخادم يعمل على :8080") log.Fatal(http.ListenAndServe(":8080", nil))}

الشرح:

  • Task — هيكل مع وسوم JSON للتسلسل الصحيح.
  • tasks — خريطة لتخزين المهام في الذاكرة (بدون قاعدة بيانات).
  • mu — كائن mutex للوصول الآمن من goroutines.
  • مساران: /api/tasks (القائمة والإنشاء) و /api/tasks/ (العمل مع مهمة واحدة بواسطة ID).


الخطوة 2: معالجات قائمة المهام (GET و POST)

سنقوم بتنفيذ الدالة tasksHandler التي تعالج GET (الحصول على جميع المهام) و POST (إنشاء مهمة جديدة).

func tasksHandler(w http.ResponseWriter, r *http.Request) {    w.Header().Set("Content-Type", "application/json")

switch r.Method { case http.MethodGet: mu.Lock() taskList := make([]Task, 0, len(tasks)) for _, task := range tasks { taskList = append(taskList, task) } mu.Unlock() json.NewEncoder(w).Encode(taskList)

case http.MethodPost: var newTask Task if err := json.NewDecoder(r.Body).Decode(&newTask); err != nil { http.Error(w, `{"error":"JSON غير صالح"}`, http.StatusBadRequest) return } mu.Lock() newTask.ID = nextID nextID++ newTask.CreatedAt = time.Now() tasks[newTask.ID] = newTask mu.Unlock()

w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(newTask)

default: http.Error(w, `{"error":"الطريقة غير مدعومة"}`, http.StatusMethodNotAllowed) }}

النقاط الرئيسية:

  • نستخدم json.NewEncoder و json.NewDecoder للعمل مع JSON.
  • في POST نتحقق من صحة JSON، ونخصص ID، ونعيد 201 Created.
  • يحمي الـ mutex البيانات أثناء الوصول المتزامن.


الخطوة 3: معالجات مهمة فردية (GET، PUT، DELETE)

الآن سنقوم بتنفيذ taskByIDHandler. نستخرج ID من URL باستخدام strings.TrimPrefix

المدونات

توصيات الكتب