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

推荐订阅源

freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Troy Hunt's Blog
T
The Exploit Database - CXSecurity.com
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
F
Fortinet All Blogs
博客园_首页
P
Proofpoint News Feed
V
Vulnerabilities – Threatpost
The Cloudflare Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
H
Heimdal Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Security Affairs
The Register - Security
The Register - Security
S
Security @ Cisco Blogs
Hugging Face - Blog
Hugging Face - Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
Schneier on Security
Schneier on Security
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
T
Tailwind CSS Blog
Hacker News: Ask HN
Hacker News: Ask HN
W
WeLiveSecurity
D
Docker
L
LangChain Blog
B
Blog RSS Feed
The Last Watchdog
The Last Watchdog
Cloudbric
Cloudbric
TaoSecurity Blog
TaoSecurity Blog
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
I
InfoQ
The Hacker News
The Hacker News
AWS News Blog
AWS News Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
宝玉的分享
宝玉的分享
I
Intezer
云风的 BLOG
云风的 BLOG
V2EX - 技术
V2EX - 技术
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

吴润写字的地方

从零构建 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 规范),尽可能的避免路由冲突问题。由于是重构项目,为了保持接口路由不变,才这么处理的。