گولانگ میں ویب سرور کی ترقی - سادہ سے پیچیدہ تک

گولانگ میں ویب سرور کی ترقی - سادہ سے پیچیدہ تک

پانچ سال پہلے میں نے شروع کیا۔ Gophish تیار کریں، اس نے گولانگ سیکھنے کا موقع فراہم کیا۔ میں نے محسوس کیا کہ گو ایک طاقتور زبان ہے، جس کی تکمیل بہت سی لائبریریوں سے ہوتی ہے۔ گو ورسٹائل ہے: خاص طور پر، اسے بغیر کسی پریشانی کے سرور سائیڈ ایپلی کیشنز تیار کرنے کے لیے استعمال کیا جا سکتا ہے۔

یہ مضمون گو میں سرور لکھنے کے بارے میں ہے۔ آئیے "ہیلو ورلڈ" جیسی سادہ چیزوں سے شروع کریں اور درج ذیل صلاحیتوں والی ایپلیکیشن کے ساتھ اختتام کریں۔

- HTTPS کے لیے Let's Encrypt کا استعمال کرنا۔
- API روٹر کے طور پر کام کرنا۔
- مڈل ویئر کے ساتھ کام کرنا۔
- جامد فائلوں کی پروسیسنگ۔
- درست شٹ ڈاؤن۔

Skillbox تجویز کرتا ہے: پریکٹیکل کورس "شروع سے ازگر کا ڈویلپر".

ہم آپ کو یاد دلاتے ہیں: "Habr" کے تمام قارئین کے لیے - "Habr" پروموشنل کوڈ کا استعمال کرتے ہوئے کسی بھی Skillbox کورس میں داخلہ لینے پر 10 rubles کی رعایت۔

ہیلو ، دنیا!

آپ Go میں بہت تیزی سے ویب سرور بنا سکتے ہیں۔ یہاں ایک ہینڈلر استعمال کرنے کی ایک مثال ہے جو اوپر وعدہ کردہ "ہیلو، ورلڈ!" واپس کرتا ہے۔

package main
 
import (
"fmt"
"net/http"
)
 
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
http.ListenAndServe(":80", nil)
}

اس کے بعد، اگر آپ ایپلی کیشن چلاتے ہیں اور صفحہ کھولتے ہیں localhost، پھر آپ کو فوری طور پر متن نظر آئے گا "ہیلو، دنیا!" (اگر سب کچھ صحیح طریقے سے کام کرتا ہے، یقینا).

ہم بعد میں ہینڈلر کو کئی بار استعمال کریں گے، لیکن پہلے یہ سمجھتے ہیں کہ سب کچھ کیسے کام کرتا ہے۔

net/http

مثال نے پیکیج کا استعمال کیا۔ net/http، یہ گو میں سرورز اور HTTP کلائنٹس دونوں کو تیار کرنے کا بنیادی ٹول ہے۔ کوڈ کو سمجھنے کے لیے، آئیے تین اہم عناصر کا مطلب سمجھتے ہیں: http.Handler، http.ServeMux اور http.Server۔

HTTP ہینڈلرز

جب ہمیں کوئی درخواست موصول ہوتی ہے تو ہینڈلر اس کا تجزیہ کرتا ہے اور جواب تیار کرتا ہے۔ Go میں ہینڈلرز کو مندرجہ ذیل طور پر لاگو کیا جاتا ہے:

type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}

پہلی مثال http.HandleFunc مددگار فنکشن کا استعمال کرتی ہے۔ یہ ایک اور فنکشن کو لپیٹتا ہے، جو بدلے میں http.ResponseWriter اور http.Request کو ServeHTTP میں لے جاتا ہے۔

دوسرے الفاظ میں، گولانگ میں ہینڈلرز کو ایک ہی انٹرفیس میں پیش کیا جاتا ہے، جو پروگرامر کو بہت سے اختیارات فراہم کرتا ہے۔ لہذا، مثال کے طور پر، مڈل ویئر کو ایک ہینڈلر کا استعمال کرتے ہوئے لاگو کیا جاتا ہے، جہاں ServeHTTP پہلے کچھ کرتا ہے اور پھر دوسرے ہینڈلر کے ServeHTTP طریقہ کو کال کرتا ہے۔

جیسا کہ اوپر بتایا گیا ہے، ہینڈلرز صرف درخواستوں کے جوابات تیار کرتے ہیں۔ لیکن وقت کے کسی خاص مقام پر کون سا خاص ہینڈلر استعمال کیا جانا چاہئے؟

روٹنگ کی درخواست کریں۔

صحیح انتخاب کرنے کے لیے، HTTP ملٹی پلیکسر استعمال کریں۔ متعدد لائبریریوں میں اسے مکسر یا روٹر کہا جاتا ہے، لیکن وہ سب ایک ہی چیز ہیں۔ ملٹی پلیکسر کا کام درخواست کے راستے کا تجزیہ کرنا اور مناسب ہینڈلر کا انتخاب کرنا ہے۔

اگر آپ کو پیچیدہ روٹنگ کے لیے سپورٹ کی ضرورت ہے، تو تھرڈ پارٹی لائبریریوں کا استعمال کرنا بہتر ہے۔ کچھ جدید ترین - گوریلا/مکس и go-chi/chi، یہ لائبریریاں بغیر کسی پریشانی کے انٹرمیڈیٹ پروسیسنگ کو نافذ کرنا ممکن بناتی ہیں۔ ان کی مدد سے، آپ وائلڈ کارڈ روٹنگ کو ترتیب دے سکتے ہیں اور بہت سے دوسرے کام انجام دے سکتے ہیں۔ ان کا فائدہ معیاری HTTP ہینڈلرز کے ساتھ مطابقت ہے۔ نتیجے کے طور پر، آپ سادہ کوڈ لکھ سکتے ہیں جس میں مستقبل میں ترمیم کی جا سکتی ہے۔

عام صورت حال میں پیچیدہ فریم ورک کے ساتھ کام کرنے کے لیے غیر معیاری حل کی ضرورت ہوگی، اور یہ ڈیفالٹ ہینڈلرز کے استعمال کو نمایاں طور پر پیچیدہ بناتا ہے۔ زیادہ تر ایپلی کیشنز بنانے کے لیے پہلے سے طے شدہ لائبریری اور ایک سادہ روٹر کا مجموعہ کافی ہوگا۔

استفسار پر کارروائی

اس کے علاوہ، ہمیں ایک ایسے جزو کی ضرورت ہے جو آنے والے کنکشنز کو "سن" دے اور تمام درخواستوں کو درست ہینڈلر کو بھیجے۔ http.Server اس کام کو آسانی سے سنبھال سکتا ہے۔

درج ذیل سے پتہ چلتا ہے کہ سرور ان تمام کاموں کے لیے ذمہ دار ہے جو کنکشن پروسیسنگ سے متعلق ہیں۔ یہ، مثال کے طور پر، TLS پروٹوکول کا استعمال کرتے ہوئے کام کرتا ہے۔ http.ListenAndServer کال کو لاگو کرنے کے لیے، ایک معیاری HTTP سرور استعمال کیا جاتا ہے۔

اب مزید پیچیدہ مثالوں کو دیکھتے ہیں۔

آئیے انکرپٹ کو شامل کرنا

پہلے سے طے شدہ طور پر، ہماری ایپلیکیشن HTTP پروٹوکول پر چلتی ہے، لیکن HTTPS پروٹوکول استعمال کرنے کی سفارش کی جاتی ہے۔ یہ Go میں مسائل کے بغیر کیا جا سکتا ہے۔ اگر آپ کو سرٹیفکیٹ اور نجی کلید موصول ہوئی ہے، تو ListenAndServeTLS کو درست سرٹیفکیٹ اور کلیدی فائلوں کے ساتھ رجسٹر کرنا کافی ہے۔

http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)

آپ ہمیشہ بہتر کر سکتے ہیں۔

چلو خفیہ ہے خودکار تجدید کے ساتھ مفت سرٹیفکیٹ فراہم کرتا ہے۔ سروس استعمال کرنے کے لیے، آپ کو ایک پیکیج کی ضرورت ہے۔ autocert.

اسے کنفیگر کرنے کا سب سے آسان طریقہ http.Serve کے ساتھ مل کر autocert.NewListener طریقہ استعمال کرنا ہے۔ یہ طریقہ آپ کو TLS سرٹیفکیٹ حاصل کرنے اور اپ ڈیٹ کرنے کی اجازت دیتا ہے جب کہ HTTP سرور درخواستوں پر کارروائی کرتا ہے:

http.Serve(autocert.NewListener("example.com"), nil)

اگر ہم براؤزر میں کھولیں۔ example.com، ہمیں ایک HTTPS جواب موصول ہوگا "ہیلو، ورلڈ!"

اگر آپ کو مزید تفصیلی کنفیگریشن کی ضرورت ہے، تو آپ کو autocert.Manager مینیجر استعمال کرنا چاہیے۔ پھر ہم اپنا http.Server مثال بناتے ہیں (اب تک ہم اسے بطور ڈیفالٹ استعمال کرتے ہیں) اور مینیجر کو TLSConfig سرور میں شامل کرتے ہیں:

m := &autocert.Manager{
Cache:      autocert.DirCache("golang-autocert"),
Prompt:     autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("example.org", "www.example.org"),
}
server := &http.Server{
    Addr:      ":443",
    TLSConfig: m.TLSConfig(),
}
server.ListenAndServeTLS("", "")

خودکار سرٹیفکیٹ کی تجدید کے ساتھ مکمل HTTPS سپورٹ کو نافذ کرنے کا یہ ایک آسان طریقہ ہے۔

حسب ضرورت راستے شامل کرنا

معیاری لائبریری میں شامل ڈیفالٹ راؤٹر اچھا ہے، لیکن یہ بہت بنیادی ہے۔ زیادہ تر ایپلی کیشنز کو زیادہ پیچیدہ روٹنگ کی ضرورت ہوتی ہے، بشمول نیسٹڈ اور وائلڈ کارڈ روٹس، یا راستے کے نمونوں اور پیرامیٹرز کو ترتیب دینے کا طریقہ کار۔

اس صورت میں یہ پیکجوں کا استعمال کرنے کے قابل ہے گوریلا/مکس и go-chi/chi. ہم بعد کے ساتھ کام کرنے کا طریقہ سیکھیں گے - ایک مثال ذیل میں دکھائی گئی ہے۔

ہمارے API کے روٹس پر مشتمل فائل api/v1/api.go دی گئی ہے:

/ HelloResponse is the JSON representation for a customized message
type HelloResponse struct {
Message string `json:"message"`
}
 
// HelloName returns a personalized JSON message
func HelloName(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
response := HelloResponse{
Message: fmt.Sprintf("Hello %s!", name),
}
jsonResponse(w, response, http.StatusOK)
}
 
// NewRouter returns an HTTP handler that implements the routes for the API
func NewRouter() http.Handler {
r := chi.NewRouter()
r.Get("/{name}", HelloName)
return r
}

ہم نے مین فائل میں روٹس کے لیے api/vq کا سابقہ ​​سیٹ کیا ہے۔

اس کے بعد ہم اسے اپنے مرکزی روٹر پر api/v1/ سابقہ ​​کے تحت واپس اپنی مرکزی ایپلی کیشن میں ماؤنٹ کر سکتے ہیں۔

// NewRouter returns a new HTTP handler that implements the main server routes
func NewRouter() http.Handler {
router := chi.NewRouter()
    router.Mount("/api/v1/", v1.NewRouter())
    return router
}
http.Serve(autocert.NewListener("example.com"), NewRouter())

پیچیدہ راستوں کے ساتھ کام کرنے میں گو کی آسانی بڑی، پیچیدہ ایپلی کیشنز کی ساخت اور دیکھ بھال کو آسان بناتی ہے۔

مڈل ویئر کے ساتھ کام کرنا

اسٹیجنگ میں ایک HTTP ہینڈلر کو دوسرے کے ساتھ لپیٹنا شامل ہوتا ہے، جس سے تصدیق، کمپریشن، لاگنگ اور کئی دیگر افعال کو تیزی سے انجام دینا ممکن ہوتا ہے۔

مثال کے طور پر، آئیے http.Handler انٹرفیس کو دیکھتے ہیں؛ ہم اسے ایک ہینڈلر لکھنے کے لیے استعمال کریں گے جو سروس استعمال کرنے والوں کی تصدیق کرتا ہے۔

func RequireAuthentication(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !isAuthenticated(r) {
            http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
            return
        }
        // Assuming authentication passed, run the original handler
        next.ServeHTTP(w, r)
    })
}

تھرڈ پارٹی راؤٹرز ہیں، جیسے chi، جو آپ کو مڈل ویئر کی فعالیت کو بڑھانے کی اجازت دیتے ہیں۔

جامد فائلوں کے ساتھ کام کرنا

Go معیاری لائبریری میں جامد مواد کے ساتھ کام کرنے کی صلاحیتیں شامل ہیں، بشمول تصاویر، JavaScript اور CSS فائلیں۔ ان تک رسائی http.FileServer فنکشن کے ذریعے کی جا سکتی ہے۔ یہ ایک ہینڈلر واپس کرتا ہے جو کسی مخصوص ڈائریکٹری سے فائلوں کی خدمت کرتا ہے۔

func NewRouter() http.Handler {
    router := chi.NewRouter()
    r.Get("/{name}", HelloName)
 
// Настройка раздачи статических файлов
staticPath, _ := filepath.Abs("../../static/")
fs := http.FileServer(http.Dir(staticPath))
    router.Handle("/*", fs)
    
    return r

یہ یقینی طور پر یاد رکھنے کے قابل ہے کہ http.Dir ڈائریکٹری کے مواد کو ظاہر کرتا ہے اگر اس میں اہم index.html فائل نہیں ہے۔ اس صورت میں، ڈائریکٹری کو سمجھوتہ کرنے سے روکنے کے لیے، آپ کو پیکیج کا استعمال کرنا چاہیے۔ unindexed.

درست بند

گو میں ایک خصوصیت بھی ہے جسے گریس فل شٹ ڈاؤن آف HTTP سرور کہا جاتا ہے۔ یہ شٹ ڈاؤن() طریقہ استعمال کرتے ہوئے کیا جا سکتا ہے۔ سرور کو ایک گوروٹین میں شروع کیا جاتا ہے، اور پھر چینل کو ایک رکاوٹ سگنل موصول ہونے کے لیے سنا جاتا ہے۔ جیسے ہی سگنل ملتا ہے، سرور بند ہوجاتا ہے، لیکن فوری طور پر نہیں، بلکہ چند سیکنڈ کے بعد۔

handler := server.NewRouter()
srv := &http.Server{
    Handler: handler,
}
 
go func() {
srv.Serve(autocert.NewListener(domains...))
}()
 
// Wait for an interrupt
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
 
// Attempt a graceful shutdown
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)

ایک نتیجہ کے طور پر

گو تقریباً عالمگیر معیاری لائبریری کے ساتھ ایک طاقتور زبان ہے۔ اس کی ڈیفالٹ صلاحیتیں بہت وسیع ہیں، اور ان کو انٹرفیس کا استعمال کرتے ہوئے بڑھایا جا سکتا ہے - یہ آپ کو واقعی قابل بھروسہ HTTP سرورز تیار کرنے کی اجازت دیتا ہے۔

Skillbox تجویز کرتا ہے:

ماخذ: www.habr.com

نیا تبصرہ شامل کریں