惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
云风的 BLOG
云风的 BLOG
IT之家
IT之家
The Register - Security
The Register - Security
博客园_首页
博客园 - 聂微东
MongoDB | Blog
MongoDB | Blog
Blog — PlanetScale
Blog — PlanetScale
The GitHub Blog
The GitHub Blog
博客园 - 【当耐特】
腾讯CDC
F
Full Disclosure
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
MyScale Blog
MyScale Blog
T
Tailwind CSS Blog
Jina AI
Jina AI
月光博客
月光博客
A
About on SuperTechFans
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Help Net Security
博客园 - Franky
Vercel News
Vercel News
美团技术团队
C
CERT Recently Published Vulnerability Notes
Security Latest
Security Latest
Scott Helme
Scott Helme
P
Proofpoint News Feed
博客园 - 三生石上(FineUI控件)
www.infosecurity-magazine.com
www.infosecurity-magazine.com
SecWiki News
SecWiki News
The Last Watchdog
The Last Watchdog
U
Unit 42
The Cloudflare Blog
N
News and Events Feed by Topic
T
Threat Research - Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
T
Tenable Blog
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
B
Blog
Webroot Blog
Webroot Blog
A
Arctic Wolf
S
SegmentFault 最新的问题
aimingoo的专栏
aimingoo的专栏
AWS News Blog
AWS News Blog
I
Intezer
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com

吴润写字的地方

从零构建 A 股 ETF 动量轮动系统:一个量化新手的完整指南 2025 年 8 月 Digest 2025 年 7 月 Digest 2025 年 6 月 Digest 2025 年 5 月 Digest 2025 年 4 月 Digest 清明桐庐行 2025 年 3 月 Digest 2024 年终总结 换车 崇明岛一日游 夜游徐汇滨江绿地 2023 年终总结 踏春之浦康休闲公园 香港澳门行 读「投资第一课」有感 皮皮玩球 Chrome 插件推荐 Go 并发之道:并发介绍 The Night Agent 我是如何使用 ChatGPT 的 2022 年终总结 在 Ubuntu 上搭建 MinIO 2021 年终总结 Golang 不可寻址的理解 Golang 的 defer 关键字使用注意事项 恭王府 强制删除 k8s terminating 状态命名空间 PromQL 计算 CPU 使用率 PromQL 如何计算变化(率) Trickster 使用 奥森的向日葵 Go Modules - checksum mismatch 错误解决 CDN 使用初探 k8s 介绍 再探 798 wu.run 域名正式使用 GoLand 使用指南 macOS 软件推荐 2020 这一年 Python 循环列表删除元素的注意事项 Mac 下的定时任务工具:Launchctl Linux 服务器搭建 VNC 可视化桌面 Jenkins 个别 job 页面打开超时的解决方法 遇见 Aamir Khan Hexo 从 GitHub 到阿里云 『从未说出口的秘密』词云分析 768 的秋天 北戴河 Outing 飞盘记 三里屯夜景 爬虫图解:轮子哥关注了哪些人 2017-06-30 GitHub+Hexo 搭建个人网站详细教程 特朗普税改 如果有一天,苹果和微信只能选一个,你会选哪一个? About | 吴润写字的地方 Links | 吴润写字的地方 Memos | 吴润写字的地方
解决 gin 路由冲突问题
2021-03-19 · via 吴润写字的地方

使用 gin 框架时,如果有两个这样的路由:

  • GET /users/:id
  • GET /users/info

gin 会报错:

panic: 'info' in new path '/users/info' conflicts with existing wildcard ':id' in existing prefix '/users/:id'

原因是这两个路由拥有一致的 HTTP 方法(指 GET/POST/PUT/DELETE 等)和请求路径前缀,且在相同的路由位置上,第一个路由是 wildcard(指 :id 这种形式)参数,第二个路由是普通字符串 info,那么就会发生路由冲突。 发生冲突该如何解决?

router.GET("/users/:id", func(ctx *gin.Context) {
        switch c.Param("id") {
        case "info":
            handlers.getUserInfo(ctx)
        default:
            handlers.GetUser(ctx)
        }
    })

思路是 :id 这个通配结果如果是 info,则拦截下来,走 /users/info 对应的 handler 逻辑;:id 通配结果非 info,则走 /users/:id 对应的 handler 逻辑。虽然不太好看,但能解决问题。

稍微复杂的路由冲突可能是这样的:

  • GET /:channelID/:programID
  • GET /redirect/:channelID/:programID

:channelIDredirect 冲突,并且两个路由的层级是不一样的,第一个有两级,第二个有三级,如何解决?

先将上面的路由转化下:

  • GET /:path1/:path2
  • GET /:path1/:path2/:path3

转换后逻辑更清晰,

  • 如果 path1 = redirect, 且 path2 和 path3 都不为空,则匹配到第二个路由,那么 path2 与 path3 分别是 channelID 和 programID

  • 如果 path1 不为空,且 path1 != redirect, 且 path2 不为空,且 path3 为空,则匹配到第一个路由,那么 path1 与 path2 分别是 channelID 和 programID

router.GET("/:path1/:path2", getHandler)       
router.GET("/:path1/:path2/:path3", getHandler)

func getHandler(ctx *gin.Context) {
    if ctx.Param("path1") == "redirect" {
        if ctx.Param("path2") != "" && ctx.Param("path3") != "" {
            ctx.Params = append(ctx.Params, gin.Param{Key: "channelID", Value: ctx.Param("path2")},
                gin.Param{Key: "programID", Value: ctx.Param("path3")})

            handlers.GetRedirectResult(ctx)
        }
    } else if ctx.Param("path1") != "" && ctx.Param("path2") != "" && ctx.Param("path3") == "" {
        ctx.Params = append(ctx.Params, gin.Param{Key: "channelID", Value: ctx.Param("path1")},
            gin.Param{Key: "programID", Value: ctx.Param("path2")})

        handlers.GetResult(ctx)
    }
}

以上的法方法是不优雅的,当遇到路由冲突的时候,可以考虑路由设计是否合理(比如是否遵循 RESTful API 规范),尽可能的避免路由冲突问题。由于是重构项目,为了保持接口路由不变,才这么处理的。