كيفية تعيين الرؤوس في طلب HTTP GET بلغة Go؟ شرح كامل مع كود
\n\nهل سبق لك أن حاولت إرسال طلب HTTP GET إلى خادم، وأعاد لك خطأ في المصادقة؟ أو ربما تجاهلت API طلبك، على الرغم من أنك كنت متأكدًا من أنه يجب أن يعمل؟ في 90% من الحالات، تكمن المشكلة في رؤوس HTTP. إنها مثل بطاقة الدخول إلى حفلة: بدون المستند الصحيح، لن يُسمح لك بالدخول.
\n\nفي هذه المقالة، سنشرح كيفية إدارة الرؤوس بشكل احترافي في طلبات HTTP GET بلغة Go (Golang). ستتعلم ليس فقط الصيغة الأساسية، ولكن أيضًا المزالق النموذجية التي يقع فيها حتى المطورون ذوو الخبرة. هيا بنا!
\n\nلماذا الرؤوس مهمة؟
\n\nتخيل أن طلب HTTP هو ظرف به رسالة. قد يكون الظرف نفسه (جسم الطلب) فارغًا، لكن المعلومات الموجودة عليه (الرؤوس) تحدد كل شيء:
\n- \n
- Content-Type — تنسيق البيانات (JSON، XML، Form) \n
- Authorization — مفتاح الوصول إلى API (Bearer token، Basic Auth) \n
- User-Agent — تعريف العميل (حتى لا يتم حظرك كروبوت) \n
- Accept — تنسيق الرد الذي تتوقعه \n
بدون الرؤوس الصحيحة، لن يفهم الخادم ببساطة ما تريده منه.
\n\nالطريقة 1: http.Get القديم الجيد (ولماذا لا يناسب)
\n\nيبدأ العديد من المبتدئين في Go باستخدام http.Get(). هذا مناسب للاختبارات، لكن هذه الطريقة لها عيب كبير — لا يمكن تعيين الرؤوس.
package main\n\nimport (\n "fmt"\n "io/ioutil"\n "net/http"\n)\n\nfunc main() {\n // لا يمكن إضافة رؤوس بهذه الطريقة!\n resp, err := http.Get("https://api.example.com/data")\n if err != nil {\n panic(err)\n }\n defer resp.Body.Close()\n\n body, _ := ioutil.ReadAll(resp.Body)\n fmt.Println(string(body))\n}\n\n\nهذا الكود يرسل ببساطة طلبًا "عارياً". إذا كانت API تتطلب رمز مصادقة — ستحصل على 401 Unauthorized. بالنسبة للمشاريع الحقيقية، هذا النهج غير مناسب.
الطريقة 2: إنشاء طلب خاص بك (الطريقة الصحيحة)
\n\nفي Go، لضبط الطلبات بدقة، يتم استخدام المُنشئ http.NewRequest(). يقوم بإرجاع كائن *http.Request يمكنك فعل أي شيء به، بما في ذلك تعيين الرؤوس.
إليك الهيكل الأساسي:
\n\npackage main\n\nimport (\n "fmt"\n "io/ioutil"\n "net/http"\n)\n\nfunc main() {\n // 1. إنشاء URL\n url := "https://api.github.com/users/golang"\n\n // 2. إنشاء طلب GET جديد\n req, err := http.NewRequest("GET", url, nil)\n if err != nil {\n panic(err)\n }\n\n // 3. تعيين الرؤوس\n req.Header.Set("User-Agent", "MyGoApp/1.0")\n req.Header.Set("Accept", "application/json")\n\n // 4. إرسال الطلب عبر عميل HTTP\n client := &http.Client{}\n resp, err := client.Do(req)\n if err != nil {\n panic(err)\n }\n defer resp.Body.Close()\n\n body, _ := ioutil.ReadAll(resp.Body)\n fmt.Println(string(body))\n}\n\n\nلاحظ: نستخدم req.Header.Set()، وليس req.Header.Add(). الفرق مهم:
- \n
- Set — يستبدل القيمة الموجودة (إذا كان هذا الرأس موجودًا بالفعل) \n
- Add — يضيف قيمة أخرى إلى القيمة الموجودة (ينشئ نسخة مكررة) \n
في معظم الحالات، استخدم Set — فهو أكثر أمانًا.
الطريقة 3: العمل مع المصادقة (Bearer Token)
\n\nالسيناريو الأكثر شيوعًا هو تمرير رمز JWT. إليك كيفية القيام بذلك بشكل صحيح:
\n\npackage main\n\nimport (\n "fmt"\n "net/http"\n)\n\nfunc main() {\n token := "your_jwt_token_here"\n url := "https://api.example.com/protected"\n\n req, _ := http.NewRequest("GET", url, nil)\n\n // تعيين رأس Authorization\n req.Heade