मुख्य सामग्री पर जाएं
मॉड्यूल 10 · पाठ 5 का 5पाठ्यक्रम में 50/50~18 min
मॉड्यूल पाठ (5/5)

मिनी-प्रोजेक्ट: एक HTTP सर्वर

net/http stdlib पैकेज उत्पादन के लिए तैयार HTTP सर्वर बनाने के लिए पर्याप्त है: रूटिंग, हैंडलर, मिडलवेयर, ग्रेसफुल शटडाउन। किसी रूपरेखा की आवश्यकता नहीं है. विशिष्ट REST API के लिए यह आधार है।

हैलो वर्ल्ड

Go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "hello %s", r.URL.Path[1:])
    })
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}

http.ListenAndServe ब्लॉक करता है और केवल त्रुटि पर वापस आता है। दूसरे तर्क के रूप में nil = "DefaultServeMux का उपयोग करें"।

हैंडलर के हस्ताक्षर

सभी संचालकों के हस्ताक्षर समान हैं:

Go
func(w http.ResponseWriter, r *http.Request)
  • w http.ResponseWriter — आउटपुट: हेडर, स्टेटस कोड, बॉडी।
  • r *http.Request — इनपुट: विधि, यूआरएल, हेडर, बॉडी, संदर्भ।

विशिष्ट पैटर्न:

Go
func ping(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodGet {
        http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
        return
    }
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK) // optional, defaults to 200
    fmt.Fprintln(w, `{"ok":true}`)
}

ServeMux के साथ रूटिंग

*http.ServeMux बेस राउटर है। चूँकि गो 1.22 यह विधि और पथ मापदंडों के साथ पैटर्न का समर्थन करता है:

Go
mux := http.NewServeMux()
mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
    id := r.PathValue("id")
    fmt.Fprintln(w, "user", id)
})
mux.HandleFunc("POST /users", createUser)

http.ListenAndServe(":8080", mux)

अधिक परिष्कृत राउटर्स (समूह, एकीकृत मिडलवेयर, रेगेक्स) के लिए chi, gorilla/mux, gin, echo हैं। stdlib 90% मामलों को कवर करता है।

डेकोरेटर के रूप में मिडलवेयर

मिडलवेयर एक फ़ंक्शन func(http.Handler) http.Handler है:

Go
func logMW(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        next.ServeHTTP(w, r)
        log.Printf("%s %s %s", r.Method, r.URL.Path, time.Since(start))
    })
}

http.ListenAndServe(":8080", logMW(mux))

उन्हें श्रृंखलाबद्ध करने के लिए: logMW(authMW(rateLimitMW(mux))). प्रत्येक मिडलवेयर अगले को सजाता है।

ठीक नियंत्रण के लिए http.Server

http.ListenAndServe(addr, h) एक शॉर्टकट है। टाइमआउट, टीएलएस और ग्रेसफुल शटडाउन के लिए आपको http.Server को तुरंत चालू करना होगा:

Go
srv := &http.Server{
    Addr:              ":8080",
    Handler:           mux,
    ReadHeaderTimeout: 5 * time.Second,
    ReadTimeout:       30 * time.Second,
    WriteTimeout:      30 * time.Second,
    IdleTimeout:       2 * time.Minute,
}
log.Fatal(srv.ListenAndServe())

सन्दर्भ सहित सुन्दर समापन

जब प्रक्रिया को SIGINT/SIGTERM प्राप्त होता है, तो आप बंद होने से पहले इन-फ़्लाइट अनुरोधों को पूरा करना चाहते हैं:

Go
ctx, stop := signal.NotifyContext(context.Background(),
    os.Interrupt, syscall.SIGTERM)
defer stop()

srv := &http.Server{Addr: ":8080", Handler: mux}
go func() {
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatal(err)
    }
}()

<-ctx.Done() // wait for the signal

shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
    log.Println("shutdown:", err)
}

srv.Shutdown नए कनेक्शन स्वीकार करना बंद कर देता है और सक्रिय कनेक्शन समाप्त होने की प्रतीक्षा करता है (समय सीमा बीतने तक)।

JSON बॉडी को पढ़ना

Go
type CreateUserReq struct {
    Name string `json:"name"`
}

func createUser(w http.ResponseWriter, r *http.Request) {
    var req CreateUserReq
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    // ... use req.Name
    w.WriteHeader(http.StatusCreated)
}

r.Body एक io.ReadCloser है: सर्वर इसे स्वचालित रूप से बंद कर देता है, लेकिन json.NewDecoder पहले JSON ऑब्जेक्ट (इनपुट को मान्य करने के लिए उपयोगी) को नहीं पढ़ता है।

अभ्यास

व्यायाम#go.m10.l5.e1
प्रयास: 0लोड हो रहा है...

रजिस्टर करें हैंडलर हेलो रूट '/' http.HandleFunc का उपयोग करें।

संपादक लोड हो रहा है...

3 प्रयासों के बाद समाधान उपलब्ध है

व्यायाम#go.m10.l5.e2
प्रयास: 0लोड हो रहा है...

http.ListenAndServe पर सर्वर का उपयोग :8080 और त्रुटि शून्य है।

संपादक लोड हो रहा है...

3 प्रयासों के बाद समाधान उपलब्ध है

Quiz#go.m10.l5.e3
तैयार

गो में HTTP हैंडलर का क्या मतलब है?

Go
func H(???) { ... }
उत्तर विकल्प