路由与中间件
基本路由
使用标准库net/http包实现基本路由。
package main
import (
"fmt"
"net/http"
)
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "About us page")
}
func main() {
// 注册路由
http.HandleFunc("/", homeHandler)
http.HandleFunc("/about", aboutHandler)
// 启动服务器
fmt.Println("Server starting on :8080...")
http.ListenAndServe(":8080", nil)
}
使用gorilla/mux
使用gorilla/mux实现更强大的路由功能。
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
// 基本路由
r.HandleFunc("/", homeHandler).Methods("GET")
r.HandleFunc("/about", aboutHandler).Methods("GET")
// 带参数的路由
r.HandleFunc("/users/{id}", userHandler).Methods("GET")
// 带查询参数的路由
r.HandleFunc("/search", searchHandler).Queries("q", "{query}").Methods("GET")
// 子路由
api := r.PathPrefix("/api").Subrouter()
api.HandleFunc("/users", apiUsersHandler).Methods("GET")
api.HandleFunc("/users", apiCreateUserHandler).Methods("POST")
// 启动服务器
http.ListenAndServe(":8080", r)
}
中间件
实现和使用中间件处理通用功能。
package main
import (
"log"
"net/http"
"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 %s %v",
r.Method,
r.RequestURI,
r.RemoteAddr,
time.Since(start),
)
})
}
// 认证中间件
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// 验证token
if !isValidToken(token) {
http.Error(w, "Invalid token", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
// 恢复中间件
func recoveryMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
log.Printf("Panic: %v", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}()
next.ServeHTTP(w, r)
})
}
func main() {
r := mux.NewRouter()
// 注册路由
r.HandleFunc("/", homeHandler)
// 使用中间件
handler := recoveryMiddleware(loggingMiddleware(authMiddleware(r)))
// 启动服务器
http.ListenAndServe(":8080", handler)
}
路由分组
使用路由分组组织相关路由。
package main
import (
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
// API路由组
api := r.PathPrefix("/api").Subrouter()
api.Use(authMiddleware)
// 用户相关路由
users := api.PathPrefix("/users").Subrouter()
users.HandleFunc("", getUsers).Methods("GET")
users.HandleFunc("", createUser).Methods("POST")
users.HandleFunc("/{id}", getUser).Methods("GET")
users.HandleFunc("/{id}", updateUser).Methods("PUT")
users.HandleFunc("/{id}", deleteUser).Methods("DELETE")
// 产品相关路由
products := api.PathPrefix("/products").Subrouter()
products.HandleFunc("", getProducts).Methods("GET")
products.HandleFunc("", createProduct).Methods("POST")
products.HandleFunc("/{id}", getProduct).Methods("GET")
products.HandleFunc("/{id}", updateProduct).Methods("PUT")
products.HandleFunc("/{id}", deleteProduct).Methods("DELETE")
// 启动服务器
http.ListenAndServe(":8080", r)
}