ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 10 · 5లో పాఠం 5కోర్సులో 50/50~18 min
మాడ్యూల్ పాఠాలు (5/5)

మినీ-ప్రాజెక్ట్: ఒక HTTP సర్వర్

ఉత్పత్తికి సిద్ధంగా ఉన్న HTTP సర్వర్‌ను రూపొందించడానికి net/http stdlib ప్యాకేజీ సరిపోతుంది: రూటింగ్, హ్యాండ్లర్లు, మిడిల్‌వేర్, ఆకర్షణీయమైన షట్‌డౌన్. ఫ్రేమ్‌వర్క్ అవసరం లేదు. సాధారణ 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 — ఇన్‌పుట్: పద్ధతి, URL, శీర్షికలు, శరీరం, సందర్భం.

సాధారణ నమూనా:

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 అనేది బేస్ రూటర్. Go 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 ఉన్నాయి. 90% కేసులను stdlib కవర్ చేస్తుంది.

డెకరేటర్‌గా మిడిల్‌వేర్

మిడిల్‌వేర్ అనేది ఒక ఫంక్షన్ 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) ఒక సత్వరమార్గం. గడువు ముగింపులు, TLS మరియు ఆకర్షణీయమైన షట్‌డౌన్ కోసం మీరు 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లోడ్ అవుతోంది...

రిజిస్ట్రార్ ఎల్'హ్యాండ్లర్ హలో సుల్లా రూట్ '/' usando http.HandleFunc.

ఎడిటర్ లోడ్ అవుతోంది…

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం#go.m10.l5.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

Avvia il server su :8080 con http.ListenAndServe e stamp l'errore se non è nil.

ఎడిటర్ లోడ్ అవుతోంది…

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

Quiz#go.m10.l5.e3
సిద్ధంగా ఉంది

గోలో హెచ్‌టిటిపి హ్యాండ్లర్‌ని క్వాల్ è లా ఫిర్మా ఇడియోమాటికా డి అన్ హ్యాండ్లర్?

Go
func H(???) { ... }
సమాధాన ఎంపికలు