Golang ۾ ويب سرور جي ترقي - سادي کان پيچيده تائين

Golang ۾ ويب سرور جي ترقي - سادي کان پيچيده تائين

پنج سال اڳ مون شروع ڪيو گوفش کي ترقي ڪريو، هن گولانگ سکڻ جو موقعو فراهم ڪيو. مون محسوس ڪيو ته گو هڪ طاقتور ٻولي آهي، ڪيترن ئي لائبريرين طرفان مڪمل ڪئي وئي آهي. Go ورسٽائل آهي: خاص طور تي، اهو استعمال ڪري سگهجي ٿو سرور-سائڊ ايپليڪيشنن کي ترقي ڪرڻ لاءِ بغير ڪنهن پريشاني جي.

هي آرٽيڪل گو ۾ سرور لکڻ بابت آهي. اچو ته سادي شين سان شروع ڪريون جيئن ”هيلو ورلڊ!“ ۽ آخر ۾ هيٺين صلاحيتن سان ايپليڪيشن سان.

- HTTPS لاءِ Let's Encrypt استعمال ڪندي.
- API روٽر طور ڪم ڪرڻ.
- مڊل ويئر سان ڪم ڪرڻ.
- جامد فائلن جي پروسيسنگ.
- صحيح بندش.

Skillbox سفارش ڪري ٿو: عملي ڪورس "شروع کان پٿون ڊولپر".

اسان توهان کي ياد ڏياريون ٿا: "Habr" جي سڀني پڙهندڙن لاءِ - 10 روبل جي رعايت جڏهن "Habr" پروموشنل ڪوڊ استعمال ڪندي ڪنهن به اسڪل باڪس ڪورس ۾ داخلا.

سلام ، دنيا!

توهان 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)
}

ان کان پوء، جيڪڏهن توهان اپليڪيشن کي هلائيندا آهيو ۽ صفحو کوليو مقامي هلو، پوءِ توهان فوري طور تي متن ڏسندا "هيلو، دنيا!" (جيڪڏهن سڀ ڪجهه صحيح ڪم ڪري، يقينا).

اسان هينڊلر کي بعد ۾ ڪيترائي ڀيرا استعمال ڪنداسين، پر پهرين اچو ته سمجھون ته سڀ ڪجهه ڪيئن ڪم ڪري ٿو.

net/http

مثال پيڪيج استعمال ڪيو net/http، اهو Go ۾ بنيادي اوزار آهي ٻنهي سرورز ۽ 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.

ان کي ترتيب ڏيڻ جو آسان طريقو autocert.NewListener طريقو استعمال ڪرڻ آهي http.Serve سان ميلاپ ۾. طريقو توهان کي 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/v1/api.go جنهن ۾ اسان جي API لاءِ رستا شامل آهن:

/ 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)
    })
}

ٽيون پارٽي روٽر آهن، جهڙوڪ چي، جيڪي توهان کي مڊل ويئر ڪارڪردگي کي وڌائڻ جي اجازت ڏين ٿا.

جامد فائلن سان ڪم ڪرڻ

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.

صحيح بندش

Go وٽ پڻ ھڪڙو خصوصيت آھي جنھن کي سڏيو ويندو آھي شاندار شٽ ڊائون آف HTTP سرور. اهو استعمال ڪري سگهجي ٿو Shutdown() طريقو. سرور هڪ گوروٽين ۾ شروع ڪيو ويو آهي، ۽ پوء چينل کي ٻڌو ويندو آهي هڪ مداخلت سگنل حاصل ڪرڻ لاء. جيئن ئي سگنل ملي ٿو، سرور بند ٿي وڃي ٿو، پر فوري طور تي نه، پر چند سيڪنڊن کان پوء.

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)

نتيجي ۾

Go هڪ طاقتور ٻولي آهي جيڪا تقريبن آفاقي معياري لائبريري سان گڏ آهي. ان جي ڊفالٽ صلاحيتون تمام وسيع آھن، ۽ اھي انٽرفيس استعمال ڪندي وڌائي سگھجن ٿيون - ھي توھان کي قابل اعتماد HTTP سرورز کي ترقي ڪرڻ جي اجازت ڏئي ٿو.

Skillbox سفارش ڪري ٿو:

جو ذريعو: www.habr.com

تبصرو شامل ڪريو