Go (Golang) Tutorial 0/45 lessons ~6 min read Lesson 31

    HTTP Server

    Go's net/http server powers millions of production APIs.

    Course progress0%
    Focus
    10 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Go's net/http server powers millions of production APIs. Register handlers with http.HandleFunc or ServeMux (enhanced in Go 1.22 with method and path patterns), wrap middleware for logging and auth, and use http.Server for graceful shutdown.

    Each incoming request runs in its own goroutine automatically. Understanding handler signatures, response writing, status codes, and Server.Shutdown with context is mandatory for backend interviews.

    This lesson builds a production-ready server with middleware, health endpoint, and graceful shutdown on SIGINT.

    The story

    Kubernetes kubelet exposes an HTTP server on port 10250 for pod lifecycle operations. Go's net/http multiplexes routes via ServeMux, wraps handlers with middleware for auth and logging, and supports graceful shutdown with server.Shutdown(ctx) when SIGTERM arrives during a rolling update on GKE.

    Every Go microservice you deploy behind an API gateway starts here: a ListenAndServe call, health endpoints, and structured request logging.

    Understanding the topic

    Key concepts

    • http.Handler interface: ServeHTTP(ResponseWriter, *Request).
    • HandlerFunc adapter converts func to Handler.
    • ResponseWriter writes headers, status, body — order matters.
    • http.Server{Addr, Handler, ReadTimeout, WriteTimeout}.
    • Shutdown(ctx) graceful stop; ListenAndServe blocks.
    • Go 1.22 ServeMux supports GET /users/{id} patterns.

    Step-by-step explanation

    1. Register routes on ServeMux or DefaultServeMux.
    2. Middleware wraps Handler: logging, auth, recovery.
    3. Handler reads r.Method, r.URL, r.Header, r.Body.
    4. w.WriteHeader(status) before body; default 200.
    5. ListenAndServe starts accepting connections.
    6. Signal handler calls srv.Shutdown(ctx) on SIGTERM.

    Practical code example

    HTTP server with middleware, health check, and graceful shutdown:

    go
    package main
    import (
    "context"
    "fmt"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
    )
    func loggingMiddleware(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 %v", r.Method, r.URL.Path, time.Since(start))
    })
    }
    func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    fmt.Fprint(w, `{"status":"ok"}`)
    })
    mux.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello from TechLearningPRO Go!\n")
    })
    srv := &http.Server{
    Addr: ":8080",
    Handler: loggingMiddleware(mux),
    ReadTimeout: 5 * time.Second,
    WriteTimeout: 10 * time.Second,
    }
    go func() {
    log.Println("listening on :8080")
    if err := srv.ListenAndServe(); err != http.ErrServerClosed {
    log.Fatal(err)
    }
    }()
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
    ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
    log.Fatal("shutdown:", err)
    }
    log.Println("server stopped gracefully")
    }

    Output

    GET /healthz HTTP/1.1 → 200 OK

    Line-by-line code explanation

    • http.HandleFunc("/healthz", healthHandler) registers a handler on the default ServeMux.
    • mux := http.NewServeMux() creates an isolated mux — preferred over global registration.
    • mux.Handle("GET /api/v1/items", handler) (Go 1.22+) supports method-aware routing.
    • func handler(w http.ResponseWriter, r *http.Request) is the standard handler signature.
    • w.WriteHeader(http.StatusOK) sets the status before writing the body.
    • json.NewEncoder(w).Encode(data) writes JSON responses directly to the ResponseWriter.
    • server := &http.Server{Addr: ":8080", Handler: mux} configures the listening server.
    • server.Shutdown(ctx) gracefully drains in-flight requests before exit.

    Key takeaway: Go 1.22 pattern routing: method + path in HandleFunc. Shutdown waits for in-flight requests. Middleware wraps Handler chain.

    Real-world use

    Where you'll use this in production

    • REST API backends for web and mobile clients.
    • Internal admin APIs and health check endpoints.
    • Webhook receivers for Stripe and GitHub events.
    • Sidecar health servers in Kubernetes pods.

    Best practices

    • Set ReadTimeout, WriteTimeout, IdleTimeout on Server.
    • Implement graceful Shutdown on SIGTERM for K8s.
    • Recovery middleware catches panics — return 500 not crash.
    • Use structured logging with request ID middleware.
    • Separate router setup from main for testability.
    • Return correct Content-Type and status codes.

    Common mistakes

    • No timeouts — slowloris and hung connections.
    • Calling WriteHeader after Write — ignored.
    • Not handling SIGTERM — K8s kills pod abruptly.
    • Panic in handler crashes process without recovery middleware.
    • Using DefaultServeMux in library code — route collisions.

    Advanced interview questions

    Q1Beginnerhttp.Handler vs HandlerFunc?
    Handler interface; HandlerFunc is adapter letting func serve as Handler.
    Q2BeginnerGraceful shutdown?
    srv.Shutdown(ctx) stops accepting, waits for in-flight requests.
    Q3IntermediateMiddleware pattern?
    func(next Handler) Handler — wrap logging, auth, metrics around inner handler.
    Q4IntermediateGo 1.22 ServeMux changes?
    Method-aware routing; path patterns with {id} wildcards; no trailing slash confusion.
    Q5AdvancedDesign production HTTP server for K8s.
    Health/readiness probes; graceful shutdown; timeouts; structured logs; pprof endpoint; metrics middleware.

    Summary

    net/http server handles each request in a goroutine. Wrap handlers with middleware for logging, auth, recovery. Configure timeouts and graceful Shutdown for production. Go 1.22 ServeMux supports method + path pattern routing. Next lesson: REST API development patterns.

    Ready to mark this lesson complete?Track your journey across the entire course.