Master HTTP programming in Go with interactive learning and quizzes
The net/http package is Go’s standard library for building HTTP servers and clients. It is powerful, easy to use, and production-ready.
The net/http package provides HTTP client and server implementations. It's part of the standard library and makes it simple to:
import "net/http"
ServeHTTP(http.ResponseWriter, *http.Request). Any struct or function that implements this can handle HTTP requests.package main
import ("fmt"; "net/http")
func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World!") }
func main() { http.HandleFunc("/", handler); http.ListenAndServe(":8080", nil) }HandleFunc: Registers a function to a route.
ListenAndServe: Starts the server and listens on port 8080.
Use this if you want custom types to handle HTTP requests.
type MyHandler struct{}
func (m MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Handled by MyHandler")) }
func main() { http.ListenAndServe(":8080", MyHandler{}) }ServeMux lets you register multiple routes.
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello route!")) })
mux.HandleFunc("/bye", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Goodbye!")) })
http.ListenAndServe(":8080", mux)
}Access URL query parameters easily:
func handler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
fmt.Fprintf(w, "Hello, %s!", name)
}Call with /hello?name=John
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost { fmt.Fprintln(w, "POST received") }
header := r.Header.Get("User-Agent")
fmt.Fprintln(w, "User-Agent:", header)
}func main() {
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
http.ListenAndServe(":8080", nil)
}Place files in the ./static/ directory. Access them at /static/file.txt
A middleware wraps an http.Handler to add extra logic.
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Request URI:", r.RequestURI)
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Welcome!")) })
loggedMux := loggingMiddleware(mux)
http.ListenAndServe(":8080", loggedMux)
}Shutdown the server cleanly on Ctrl+C:
func gracefulShutdown(server *http.Server, quit <-chan os.Signal, done chan<- bool) {
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
server.Shutdown(ctx)
done <- true
}func jsonHandler(w http.ResponseWriter, r *http.Request) {
response := map[string]string{"message": "Hello JSON"}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}