Contents

Go路由注册方法

mux := http.NewServeMux()http.HandleFunc 是 Go 语言中两种不同的路由注册方式,它们的区别主要体现在以下几个方面:


1. 路由注册的方式

  • http.NewServeMux():

    • http.NewServeMux() 创建一个新的 ServeMux 实例(即一个新的多路复用器)。
    • 通过 mux.HandleFunc()mux.Handle() 注册路由。
    • 这种方式允许你创建多个独立的路由器(ServeMux),每个路由器可以单独使用或组合使用。
    • 示例:
      mux := http.NewServeMux()
      mux.HandleFunc("/", rootHandler)
      mux.HandleFunc("/about", aboutHandler)
  • http.HandleFunc():

    • http.HandleFunc() 是直接使用 Go 标准库中的默认 ServeMux(即 http.DefaultServeMux)。
    • 通过 http.HandleFunc()http.Handle() 注册路由。
    • 这种方式会将路由注册到全局的默认路由器中,适合简单的应用场景。
    • 示例:
      http.HandleFunc("/", homeHandler)
      http.HandleFunc("/about", aboutHandler)

2. 路由器的独立性

  • http.NewServeMux():

    • 你可以创建多个独立的 ServeMux 实例,每个实例可以单独使用或组合使用。
    • 例如,你可以为不同的模块或功能创建不同的路由器,然后将它们组合在一起。
    • 示例:
      mux1 := http.NewServeMux()
      mux1.HandleFunc("/api/v1", apiV1Handler)
      
      mux2 := http.NewServeMux()
      mux2.HandleFunc("/api/v2", apiV2Handler)
      
      // 组合多个路由器
      mainMux := http.NewServeMux()
      mainMux.Handle("/v1/", mux1)
      mainMux.Handle("/v2/", mux2)
  • http.HandleFunc():

    • 所有的路由都注册到全局的默认路由器 http.DefaultServeMux 中。
    • 这种方式不适合需要模块化或分层次路由的场景。

3. 灵活性

  • http.NewServeMux():

    • 更灵活,适合需要自定义路由器的场景。
    • 你可以为不同的路由组设置不同的中间件或配置。
    • 示例:
      mux := http.NewServeMux()
      mux.HandleFunc("/", rootHandler)
      mux.HandleFunc("/admin", adminHandler)
      
      // 使用中间件
      loggedMux := loggingMiddleware(mux)
      http.ListenAndServe(":8080", loggedMux)
  • http.HandleFunc():

    • 灵活性较低,适合简单的应用场景。
    • 所有的路由共享同一个全局路由器,无法为不同的路由组设置不同的中间件或配置。

4. 启动服务器的方式

  • http.NewServeMux():

    • 启动服务器时需要显式指定自定义的 ServeMux
    • 示例:
      mux := http.NewServeMux()
      mux.HandleFunc("/", rootHandler)
      http.ListenAndServe(":8080", mux)
  • http.HandleFunc():

    • 启动服务器时不需要显式指定路由器,默认使用 http.DefaultServeMux
    • 示例:
      http.HandleFunc("/", homeHandler)
      http.ListenAndServe(":8080", nil) // 使用默认的 ServeMux

5. 适用场景

  • http.NewServeMux():

    • 适合需要模块化、分层路由或自定义路由器的场景。
    • 适合大型项目或需要灵活配置的项目。
  • http.HandleFunc():

    • 适合小型项目或简单的应用场景。
    • 适合快速原型开发或不需要复杂路由配置的项目。

6. 代码示例对比

使用 http.NewServeMux()

package main

import (
	"fmt"
	"net/http"
)

func rootHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Root Handler")
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "About Handler")
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/", rootHandler)
	mux.HandleFunc("/about", aboutHandler)

	fmt.Println("Server is running on http://localhost:8080")
	http.ListenAndServe(":8080", mux)
}

使用 http.HandleFunc()

package main

import (
	"fmt"
	"net/http"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Home Handler")
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "About Handler")
}

func main() {
	http.HandleFunc("/", homeHandler)
	http.HandleFunc("/about", aboutHandler)

	fmt.Println("Server is running on http://localhost:8080")
	http.ListenAndServe(":8080", nil)
}

总结

特性http.NewServeMux()http.HandleFunc()
路由器实例自定义 ServeMux 实例使用全局默认的 http.DefaultServeMux
灵活性高,支持模块化和分层路由低,适合简单场景
适用场景大型项目或需要复杂路由配置的项目小型项目或快速原型开发
启动服务器方式需要显式指定自定义 ServeMux无需显式指定,默认使用全局路由器

根据项目需求选择合适的方式:如果需要灵活性和模块化,推荐使用 http.NewServeMux();如果项目简单且不需要复杂配置,可以使用 http.HandleFunc()