Go 1.22 now ships with an HTTP server multiplexer, so there is no longer a need to include routing libraries like httprouter or chi.
package main
import (
"errors"
"fmt"
"log"
"net/http"
"time"
)
func timeHandler(w http.ResponseWriter, r *http.Request) {
now := time.Now().Format(time.RFC1123)
fmt.Fprintf(w, "The time is: %v", now)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /time", timeHandler)
err := http.ListenAndServe(":3000", mux)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("Server startup failed: %s", err)
}
}
package main
import (
"errors"
"fmt"
"log"
"net/http"
)
func itemHandler(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
fmt.Fprintf(w, "received request for item: %v", id)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /item/{id}", itemHandler)
err := http.ListenAndServe(":3000", mux)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("Server startup failed: %s", err)
}
}
package main
import (
"errors"
"fmt"
"log"
"net/http"
"time"
)
type Middleware func(handler http.Handler) http.Handler
func CombineMiddleware(middlewares ...Middleware) Middleware {
return func(next http.Handler) http.Handler {
for _, mw := range middlewares {
next = mw(next)
}
return next
}
}
func RequestLogger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
defer func() {
log.Println(r.Method, r.URL.Path, time.Since(start))
}()
next.ServeHTTP(w, r)
})
}
func timeHandler(w http.ResponseWriter, r *http.Request) {
now := time.Now().Format(time.RFC1123)
fmt.Fprintf(w, "The time is: %v", now)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /time", timeHandler)
middlewares := CombineMiddleware(
RequestLogger,
)
err := http.ListenAndServe(":3000", middlewares(mux))
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("Server startup failed: %s", err)
}
}
package main
import (
"errors"
"fmt"
"log"
"net/http"
"time"
)
func timeHandler(w http.ResponseWriter, r *http.Request) {
now := time.Now().Format(time.RFC1123)
fmt.Fprintf(w, "The time is: %v", now)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /time", timeHandler)
v1 := http.NewServeMux()
v1.Handle("/v1/", http.StripPrefix("/v1", mux))
err := http.ListenAndServe(":3000", mux)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("Server startup failed: %s", err)
}
}
Also, you can use httptest to test HTTP request handlers.