You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go的julienschmidt/httprouter中实现嵌套路由?

httprouter嵌套路由404问题解决

你的代码出现404的原因有两个核心问题:

1. 顶层路由匹配规则不匹配请求路径

httprouter的路由默认是精确匹配,你定义的顶层路由/api只会匹配路径完全等于/api的请求,不会匹配/api/foo或/api/bar这类带后缀的路径。

2. 子路由收到的请求路径未去除前缀

即使顶层路由能转发请求,子router收到的请求URL是完整的/api/foo,但你在子router里定义的是/foo,两者路径不匹配,导致子router也找不到对应的处理函数。

修复方案

你需要修改顶层路由的匹配规则,同时去除请求路径中的/api前缀,再交给子router处理。示例代码如下:

package main

import (
    "log"
    "net/http"

    "github.com/julienschmidt/httprouter"
)

func apiFoo(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Success: /api/foo"))
}
func apiBar(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Success: /api/bar"))
}

func main() {
    // 子router:处理/api前缀下的具体路由
    apiRouter := httprouter.New()
    apiRouter.HandlerFunc(http.MethodGet, "/foo", apiFoo)
    apiRouter.HandlerFunc(http.MethodGet, "/bar", apiBar)

    // 顶层router:匹配所有/api开头的请求
    rootRouter := httprouter.New()
    // 使用/api/*匹配所有/api开头的路径,并用http.StripPrefix去除/api前缀后交给子router
    rootRouter.Handler(http.MethodGet, "/api/*", http.StripPrefix("/api", apiRouter))

    // 如果需要给所有API路由加中间件,只需包装子router即可
    // 示例中间件:
    // apiMiddleware := func(next http.Handler) http.Handler {
    //     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    //         log.Println("API请求中间件触发")
    //         next.ServeHTTP(w, r)
    //     })
    // }
    // rootRouter.Handler(http.MethodGet, "/api/*", apiMiddleware(http.StripPrefix("/api", apiRouter)))

    log.Fatal(http.ListenAndServe(":8080", rootRouter))
}

关键说明

  • 用/api/*作为顶层路由规则,*是httprouter的通配符,会匹配/api之后的所有路径。
  • http.StripPrefix("/api", apiRouter)会将请求路径中的/api前缀去掉,比如把/api/foo变成/foo,这样子router里定义的/foo就能正确匹配。
  • 若要给所有API路由统一添加中间件,只需将中间件包装在http.StripPrefix返回的Handler外层即可,无需逐个修改子router的路由。

内容的提问来源于stack exchange,提问作者Yawar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:10:39