गोलांग में वेब सर्वर विकास - सरल से जटिल तक

गोलांग में वेब सर्वर विकास - सरल से जटिल तक

पांच साल पहले मैंने शुरुआत की थी गोफिश विकसित करेंइससे गोलांग सीखने का अवसर मिला। मुझे एहसास हुआ कि गो एक शक्तिशाली भाषा है, जो कई पुस्तकालयों से पूरित है। गो बहुमुखी है: विशेष रूप से, इसका उपयोग बिना किसी समस्या के सर्वर-साइड एप्लिकेशन विकसित करने के लिए किया जा सकता है।

यह आलेख गो में सर्वर लिखने के बारे में है। आइए "हैलो वर्ल्ड!" जैसी सरल चीजों से शुरू करें और निम्नलिखित क्षमताओं वाले एक एप्लिकेशन के साथ समाप्त करें:

- HTTPS के लिए Let's Encrypt का उपयोग करना।
- एपीआई राउटर के रूप में कार्य करना।
- मिडलवेयर के साथ काम करना।
- स्थैतिक फ़ाइलों का प्रसंस्करण।
- सही शटडाउन.

स्किलबॉक्स अनुशंसा करता है: व्यावहारिक पाठ्यक्रम "शुरुआत से पायथन डेवलपर".

अनुस्मारक: "हैबर" के सभी पाठकों के लिए - "हैबर" प्रचार कोड का उपयोग करके किसी भी स्किलबॉक्स पाठ्यक्रम में नामांकन करते समय 10 रूबल की छूट।

नमस्ते दुनिया!

आप गो में बहुत जल्दी एक वेब सर्वर बना सकते हैं। यहां एक हैंडलर का उपयोग करने का एक उदाहरण दिया गया है जो ऊपर वादा किया गया "हैलो, वर्ल्ड!" लौटाता है।

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

इसके बाद अगर आप एप्लिकेशन को रन करेंगे और पेज को ओपन करेंगे स्थानीय होस्ट, तो आपको तुरंत "हैलो, दुनिया!" टेक्स्ट दिखाई देगा। (बेशक, अगर सब कुछ सही ढंग से काम करता है)।

हम बाद में हैंडलर का कई बार उपयोग करेंगे, लेकिन पहले यह समझ लें कि सब कुछ कैसे काम करता है।

नेट/http

उदाहरण में पैकेज का उपयोग किया गया net/http, यह सर्वर और HTTP क्लाइंट दोनों को विकसित करने के लिए गो में प्राथमिक उपकरण है। कोड को समझने के लिए, आइए तीन महत्वपूर्ण तत्वों का अर्थ समझें: http.Handler, http.ServeMux और http.Server।

HTTP हैंडलर

जब हमें कोई अनुरोध प्राप्त होता है, तो हैंडलर उसका विश्लेषण करता है और प्रतिक्रिया उत्पन्न करता है। गो में हैंडलर निम्नानुसार कार्यान्वित किए जाते हैं:

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

पहला उदाहरण http.HandleFunc हेल्पर फ़ंक्शन का उपयोग करता है। यह एक अन्य फ़ंक्शन को लपेटता है, जो बदले में http.ResponseWriter और http.Request को ServeHTTP में ले जाता है।

दूसरे शब्दों में, गोलांग में हैंडलर को एक ही इंटरफ़ेस में प्रस्तुत किया जाता है, जो प्रोग्रामर को बहुत सारे विकल्प देता है। इसलिए, उदाहरण के लिए, मिडलवेयर को एक हैंडलर का उपयोग करके कार्यान्वित किया जाता है, जहां सर्वएचटीटीपी पहले कुछ करता है और फिर दूसरे हैंडलर की सर्वएचटीटीपी विधि को कॉल करता है।

जैसा कि ऊपर उल्लेख किया गया है, हैंडलर केवल अनुरोधों पर प्रतिक्रियाएँ उत्पन्न करते हैं। लेकिन किसी विशेष समय पर किस विशेष हैंडलर का उपयोग किया जाना चाहिए?

रूटिंग का अनुरोध करें

सही विकल्प चुनने के लिए, HTTP मल्टीप्लेक्सर का उपयोग करें। कई पुस्तकालयों में इसे मक्सर या राउटर कहा जाता है, लेकिन वे सभी एक ही चीज़ हैं। मल्टीप्लेक्सर का कार्य अनुरोध पथ का विश्लेषण करना और उपयुक्त हैंडलर का चयन करना है।

यदि आपको जटिल रूटिंग के लिए समर्थन की आवश्यकता है, तो तृतीय-पक्ष लाइब्रेरी का उपयोग करना बेहतर है। कुछ सबसे उन्नत - गोरिल्ला/मक्स и गो-ची/ची, ये पुस्तकालय बिना किसी समस्या के मध्यवर्ती प्रसंस्करण को लागू करना संभव बनाते हैं। उनकी मदद से, आप वाइल्डकार्ड रूटिंग कॉन्फ़िगर कर सकते हैं और कई अन्य कार्य कर सकते हैं। उनका लाभ मानक HTTP हैंडलर के साथ संगतता है। परिणामस्वरूप, आप सरल कोड लिख सकते हैं जिसे भविष्य में संशोधित किया जा सकता है।

सामान्य स्थिति में जटिल ढांचे के साथ काम करने के लिए गैर-मानक समाधान की आवश्यकता होगी, और यह डिफ़ॉल्ट हैंडलर के उपयोग को काफी जटिल बनाता है। अधिकांश एप्लिकेशन बनाने के लिए, डिफ़ॉल्ट लाइब्रेरी और एक साधारण राउटर का संयोजन पर्याप्त होगा।

क्वेरी प्रोसेसिंग

इसके अलावा, हमें एक घटक की आवश्यकता है जो आने वाले कनेक्शनों को "सुनेगा" और सभी अनुरोधों को सही हैंडलर पर रीडायरेक्ट करेगा। http.Server इस कार्य को आसानी से संभाल सकता है।

निम्नलिखित से पता चलता है कि सर्वर कनेक्शन प्रोसेसिंग से संबंधित सभी कार्यों के लिए ज़िम्मेदार है। उदाहरण के लिए, यह टीएलएस प्रोटोकॉल का उपयोग करके काम करता है। http.ListenAndServer कॉल को लागू करने के लिए, एक मानक HTTP सर्वर का उपयोग किया जाता है।

आइए अब अधिक जटिल उदाहरण देखें।

आइए एन्क्रिप्ट करें को जोड़ा जा रहा है

डिफ़ॉल्ट रूप से, हमारा एप्लिकेशन HTTP प्रोटोकॉल पर चलता है, लेकिन HTTPS प्रोटोकॉल का उपयोग करने की अनुशंसा की जाती है। यह गो में बिना किसी समस्या के किया जा सकता है। यदि आपको प्रमाणपत्र और निजी कुंजी प्राप्त हुई है, तो यह सही प्रमाणपत्र और कुंजी फ़ाइलों के साथ लिसनएंडसर्वटीएलएस को पंजीकृत करने के लिए पर्याप्त है।

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

आप हमेशा बेहतर कर सकते हैं.

चलो एन्क्रिप्ट करें स्वचालित नवीनीकरण के साथ निःशुल्क प्रमाणपत्र प्रदान करता है। सेवा का उपयोग करने के लिए, आपको एक पैकेज की आवश्यकता है autocert.

इसे कॉन्फ़िगर करने का सबसे आसान तरीका http.Serve के साथ संयोजन में autocert.NewListener विधि का उपयोग करना है। 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 समर्थन लागू करने का यह एक आसान तरीका है।

कस्टम मार्ग जोड़ना

मानक लाइब्रेरी में शामिल डिफ़ॉल्ट राउटर अच्छा है, लेकिन यह बहुत बुनियादी है। अधिकांश अनुप्रयोगों को अधिक जटिल रूटिंग की आवश्यकता होती है, जिसमें नेस्टेड और वाइल्डकार्ड रूट, या पथ पैटर्न और पैरामीटर सेट करने की प्रक्रिया शामिल है।

इस मामले में यह पैकेज का उपयोग करने लायक है गोरिल्ला/मक्स и गो-ची/ची. हम बाद वाले के साथ काम करना सीखेंगे - एक उदाहरण नीचे दिखाया गया है।

फ़ाइल 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
}

हम मुख्य फ़ाइल में मार्गों के लिए एपीआई/वीक्यू उपसर्ग सेट करते हैं।

फिर हम इसे अपने मुख्य एप्लिकेशन में एपीआई/वी1/ उपसर्ग के तहत अपने मुख्य राउटर पर माउंट कर सकते हैं:

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

ची जैसे तृतीय पक्ष राउटर हैं, जो आपको मिडलवेयर कार्यक्षमता को बढ़ाने की अनुमति देते हैं।

स्थिर फ़ाइलों के साथ कार्य करना

गो मानक लाइब्रेरी में छवियों, जावास्क्रिप्ट और सीएसएस फ़ाइलों सहित स्थिर सामग्री के साथ काम करने की क्षमताएं शामिल हैं। उन्हें 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 सर्वर विकसित करने की अनुमति देता है।

स्किलबॉक्स अनुशंसा करता है:

स्रोत: www.habr.com

एक टिप्पणी जोड़ें