路由与中间件

基本路由

使用标准库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)
}