مقدمة: لماذا يحتاج مشروع Go الخاص بك إلى قائد
\n\nتخيل أوركسترا سيمفونية. لديك آلات الكمان (خدمة المستخدمين)، آلات النفخ (خدمة الطلبات)، آلات الإيقاع (خدمة الدفع). كل آلة رائعة بمفردها، لكن بدون قائد، سيعزفون بشكل عشوائي. في عالم الخدمات المصغرة على Go، API Gateway هو ذلك القائد.
\n\nعندما تكتب بلغة Go، فأنت معتاد على الأداء والبساطة والأناقة. ولكن بمجرد أن يتجاوز عدد الخدمات 3-4، تبدأ الفوضى: العملاء لا يعرفون أين يذهبون، تتكرر المصادقة في كل خدمة، ويصبح المراقبة صداعًا. API Gateway لخدمات Go يحل هذه المشاكل دفعة واحدة.
\n\nفي هذه المقالة، لن نتحدث فقط عن النظرية. سنأخذ Go، والمكتبة القياسية، وحزمة أو اثنتين من الحزم الشائعة، لبناء بوابتنا الخاصة. هل أنت مستعد للقيادة؟ هيا بنا!
\n\nما هو API Gateway ولماذا تحتاجه في Go؟
\n\nAPI Gateway هو نقطة دخول واحدة لجميع طلبات العملاء إلى خدمات الخلفية الخاصة بك. تخيل أن لديك:
\n\n- \n
user-service:8081— التسجيل والملفات الشخصية \norder-service:8082— سلة التسوق والطلبات \npayment-service:8083— المعاملات \n
بدون بوابة، يجب على العميل معرفة عناوين الخدمات الثلاث. مع API Gateway على Go، يطرق فقط على api.example.com، وتقرر البوابة بنفسها أين توجه الطلب.
الوظائف الرئيسية للبوابة
\n\n- \n
- التوجيه — إعادة توجيه الطلبات إلى الخدمة المناسبة \n
- المصادقة والتفويض — التحقق من رموز JWT في مكان واحد \n
- تحديد المعدل — الحماية من هجمات DDoS والتحميل الزائد \n
- تجميع البيانات — جمع الردود من عدة خدمات في رد واحد \n
- موازنة التحميل — توزيع الطلبات بين النسخ \n
Go مثالي لهذا الدور: فهو خفيف وسريع ويسمح بمعالجة آلاف الطلبات في الثانية على نواة واحدة.
\n\nكتابة API Gateway بسيط على Go: من الفكرة إلى الكود
\n\nلنقم ببناء Go API Gateway بسيط لكنه عملي. سنستخدم فقط المكتبة القياسية net/http وحزمة httputil.ReverseProxy للوكيل العكسي.
الخطوة 1: التوجيه الأساسي
\n\nلنبدأ بشيء بسيط: توجيه الطلبات إلى خدمات مختلفة بناءً على المسار.
\n\npackage main\n\nimport (\n "log"\n "net/http"\n "net/http/httputil"\n "net/url"\n)\n\nfunc main() {\n // خدمة المستخدمين\n userServiceURL, _ := url.Parse("http://localhost:8081")\n userProxy := httputil.NewSingleHostReverseProxy(userServiceURL)\n\n // خدمة الطلبات\n orderServiceURL, _ := url.Parse("http://localhost:8082")\n orderProxy := httputil.NewSingleHostReverseProxy(orderServiceURL)\n\n http.HandleFunc("/api/users/", func(w http.ResponseWriter, r *http.Request) {\n log.Printf("إعادة توجيه الطلب إلى user-service: %s", r.URL.Path)\n userProxy.ServeHTTP(w, r)\n })\n\n http.HandleFunc("/api/orders/", func(w http.ResponseWriter, r *http.Request) {\n log.Printf("إعادة توجيه الطلب إلى order-service: %s", r.URL.Path)\n orderProxy.ServeHTTP(w, r)\n })\n\n log.Println("API Gateway يعمل على :8080")\n log.Fatal(http.ListenAndServe(":8080", nil))\n}\n\n\nهذا الكود يقوم بالفعل بـ 80% من العمل: أي طلب إلى /api/users/ يذهب إلى user-service، وأي طلب إلى /api/orders/ يذهب إلى order-service. لكن أين المصادقة؟
الخطوة 2: إضافة middleware لـ JWT
\n\nالسحر الحقيقي لـ API Gateway على Go يحدث في middleware. دعنا نضيف التحقق من رمز JWT قبل الوكيل العكسي.
\n\npackage main\n\nimport (\n "context"\n "log"\n "net/http"\n "net/http/htt"