عميل HTTP بلغة Go: إجراء الطلبات بشكل صحيح من الألف إلى الياء
Go (Golang) هي لغة تشتهر ببساطتها وأدائها، خاصة في مجال برمجة الشبكات. توفر الحزمة المدمجة net/http عميل HTTP قوي ومرن، مناسب لكل من الطلبات البسيطة والأنظمة المعقدة عالية التحميل. في هذه المقالة، سنشرح كيفية استخدام عميل HTTP في Go بشكل صحيح، بدءًا من الطلبات الأساسية وصولاً إلى الإعدادات المتقدمة.
1. الأساسيات: إنشاء وتنفيذ الطلبات البسيطة
أبسط طريقة لإجراء طلب HTTP في Go هي استخدام الدوال المساعدة من الحزمة net/http، مثل http.Get و http.Post. ومع ذلك، يُوصى باستخدام إنشاء صريح للعميل والطلب في كود الإنتاج.
طلب GET أساسي:
package main
import ( "fmt" "io/ioutil" "net/http")
func main() { // إنشاء عميل جديد client := &http.Client{}
// إنشاء طلب req, err := http.NewRequest("GET", "https://api.example.com/data", nil) if err != nil { fmt.Println("خطأ في إنشاء الطلب:", err) return }
// تنفيذ الطلب resp, err := client.Do(req) if err != nil { fmt.Println("خطأ في تنفيذ الطلب:", err) return } defer resp.Body.Close()
// قراءة جسم الرد body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("خطأ في قراءة الرد:", err) return }
fmt.Println("الحالة:", resp.Status) fmt.Println("الجسم:", string(body))}طلب POST مع جسم JSON:
package main
import ( "bytes" "encoding/json" "fmt" "net/http")
type Payload struct { Name string `json:"name"` Email string `json:"email"`}
func main() { payload := Payload{Name: "John", Email: "john@example.com"} jsonData, _ := json.Marshal(payload)
client := &http.Client{} req, err := http.NewRequest("POST", "https://api.example.com/users", bytes.NewBuffer(jsonData)) if err != nil { fmt.Println("خطأ:", err) return }
// تعيين الرؤوس req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer your-token")
resp, err := client.Do(req) if err != nil { fmt.Println("خطأ:", err) return } defer resp.Body.Close()
fmt.Println("الحالة:", resp.Status)}2. إدارة المهلات والسياقات
من أكثر الأخطاء شيوعًا عدم وجود مهلات. بدونها، قد يتعطل عميلك إلى أجل غير مسمى في انتظار رد من الخادم. في Go، هناك طريقتان رئيسيتان لإدارة وقت الانتظار.
المهلة على مستوى العميل:
client := &http.Client{ Timeout: 10 * time.Second, // مهلة إجمالية للطلب بأكمله}المهلة باستخدام السياق (مُوصى به):
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", "https://api.example.com/data", nil)if err != nil { log.Fatal(err)}
resp, err := client.Do(req)if err != nil { // التحقق مما إذا كانت المهلة قد انتهت if errors.Is(err, context.DeadlineExceeded) { fmt.Println("تجاوز الطلب المهلة") } else { fmt.Println("خطأ:", err) } return}defer resp.Body.Close()استخدام السياق يوفر مرونة أكبر: يمكنك إلغاء الطلب في أي وقت (مثلًا عند إغلاق التطبيق) وتمرير القيم عبر السياق.
3. معالجة الأخطاء والمحاولات المتكررة
الشبكة غير موثوقة، لذلك يجب أن يكون عميلك مستعدًا للأعطال المؤقتة.