路由基础 #
一、路由概述 #
1.1 什么是路由 #
路由是将HTTP请求映射到处理函数的机制。Fiber提供了强大而灵活的路由系统。
text
HTTP请求 → 路由匹配 → 处理函数 → 响应
1.2 路由组成 #
一个完整的路由由以下部分组成:
go
app.Get("/users/:id", handler)
// 组成部分:
// - Get: HTTP方法
// - /users/:id: 路由路径
// - handler: 处理函数
二、基本路由 #
2.1 定义路由 #
go
package main
import "github.com/gofiber/fiber/v2"
func main() {
app := fiber.New()
// GET请求
app.Get("/hello", func(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
})
// POST请求
app.Post("/users", func(c *fiber.Ctx) error {
return c.SendString("Create User")
})
// PUT请求
app.Put("/users/:id", func(c *fiber.Ctx) error {
return c.SendString("Update User")
})
// DELETE请求
app.Delete("/users/:id", func(c *fiber.Ctx) error {
return c.SendString("Delete User")
})
// PATCH请求
app.Patch("/users/:id", func(c *fiber.Ctx) error {
return c.SendString("Patch User")
})
// HEAD请求
app.Head("/info", func(c *fiber.Ctx) error {
return c.SendString("Head Request")
})
// OPTIONS请求
app.Options("/options", func(c *fiber.Ctx) error {
return c.SendString("Options Request")
})
app.Listen(":3000")
}
2.2 匹配所有方法 #
go
// 匹配所有HTTP方法
app.All("/api", func(c *fiber.Ctx) error {
return c.SendString("All methods")
})
// 使用Use匹配所有方法(作为中间件)
app.Use("/middleware", func(c *fiber.Ctx) error {
return c.Next()
})
2.3 多个处理函数 #
go
// 多个处理函数链式调用
app.Get("/chain",
func(c *fiber.Ctx) error {
c.Set("X-Custom", "value")
return c.Next()
},
func(c *fiber.Ctx) error {
return c.SendString("Chain handlers")
},
)
三、路由参数 #
3.1 路径参数 #
go
// 必需参数
app.Get("/users/:id", func(c *fiber.Ctx) error {
id := c.Params("id")
return c.SendString("User ID: " + id)
})
// 可选参数
app.Get("/users/:id?", func(c *fiber.Ctx) error {
id := c.Params("id", "default")
return c.SendString("User ID: " + id)
})
// 多个参数
app.Get("/users/:userId/posts/:postId", func(c *fiber.Ctx) error {
userId := c.Params("userId")
postId := c.Params("postId")
return c.SendString("User: " + userId + ", Post: " + postId)
})
// 整数参数
app.Get("/page/:num", func(c *fiber.Ctx) error {
num := c.ParamsInt("num", 1)
return c.SendString("Page: " + strconv.Itoa(num))
})
3.2 通配符参数 #
go
// 单个通配符
app.Get("/files/*", func(c *fiber.Ctx) error {
path := c.Params("*")
return c.SendString("File path: " + path)
})
// 命名通配符
app.Get("/files/*filepath", func(c *fiber.Ctx) error {
filepath := c.Params("filepath")
return c.SendString("File: " + filepath)
})
// 组合使用
app.Get("/api/:version/*path", func(c *fiber.Ctx) error {
version := c.Params("version")
path := c.Params("path")
return c.SendString("Version: " + version + ", Path: " + path)
})
3.3 查询参数 #
go
app.Get("/search", func(c *fiber.Ctx) error {
// 获取单个参数
q := c.Query("q")
// 带默认值
page := c.Query("page", "1")
// 获取所有参数
queries := c.Queries()
return c.JSON(fiber.Map{
"query": q,
"page": page,
"queries": queries,
})
})
四、路由配置 #
4.1 严格路由 #
go
// 默认情况下,/foo 和 /foo/ 被视为相同
app := fiber.New(fiber.Config{
StrictRouting: true, // 区分 /foo 和 /foo/
})
app.Get("/foo", func(c *fiber.Ctx) error {
return c.SendString("foo")
})
app.Get("/foo/", func(c *fiber.Ctx) error {
return c.SendString("foo/")
})
4.2 大小写敏感 #
go
app := fiber.New(fiber.Config{
CaseSensitive: true, // 区分大小写
})
app.Get("/Foo", func(c *fiber.Ctx) error {
return c.SendString("Foo")
})
// /Foo 匹配
// /foo 不匹配
4.3 路由配置选项 #
go
app := fiber.New(fiber.Config{
// 严格路由
StrictRouting: false,
// 大小写敏感
CaseSensitive: false,
// 不可变
Immutable: false,
// 严格模式(解析时严格检查)
UnescapePath: true,
// 启用路由追踪
EnableTrustedProxyCheck: true,
})
五、路由分组 #
5.1 基本分组 #
go
func main() {
app := fiber.New()
// API v1分组
v1 := app.Group("/api/v1")
v1.Get("/users", getUsers)
v1.Get("/users/:id", getUser)
v1.Post("/users", createUser)
// API v2分组
v2 := app.Group("/api/v2")
v2.Get("/users", getUsersV2)
v2.Get("/users/:id", getUserV2)
app.Listen(":3000")
}
5.2 嵌套分组 #
go
func main() {
app := fiber.New()
api := app.Group("/api")
// 用户模块
users := api.Group("/users")
users.Get("/", listUsers)
users.Get("/:id", getUser)
users.Post("/", createUser)
// 用户下的文章
posts := users.Group("/:userId/posts")
posts.Get("/", listPosts)
posts.Get("/:postId", getPost)
// 最终路由:
// GET /api/users
// GET /api/users/:id
// POST /api/users
// GET /api/users/:userId/posts
// GET /api/users/:userId/posts/:postId
app.Listen(":3000")
}
5.3 分组中间件 #
go
func main() {
app := fiber.New()
// API分组带中间件
api := app.Group("/api", func(c *fiber.Ctx) error {
c.Set("X-API-Version", "1.0")
return c.Next()
})
// 认证分组
auth := api.Group("/auth", authMiddleware)
auth.Get("/profile", getProfile)
auth.Get("/settings", getSettings)
// 公开路由
api.Get("/public", func(c *fiber.Ctx) error {
return c.SendString("Public API")
})
app.Listen(":3000")
}
func authMiddleware(c *fiber.Ctx) error {
token := c.Get("Authorization")
if token == "" {
return c.Status(401).JSON(fiber.Map{
"error": "Unauthorized",
})
}
return c.Next()
}
六、路由命名 #
6.1 命名路由 #
go
func main() {
app := fiber.New()
// 命名路由
app.Get("/users/:id", func(c *fiber.Ctx) error {
return c.SendString("User")
}).Name("user.show")
app.Post("/users", func(c *fiber.Ctx) error {
return c.SendString("Create User")
}).Name("user.store")
// 获取路由名称
app.Get("/routes", func(c *fiber.Ctx) error {
routes := app.GetRoutes()
var names []string
for _, route := range routes {
names = append(names, route.Name)
}
return c.JSON(names)
})
app.Listen(":3000")
}
6.2 生成URL #
go
func main() {
app := fiber.New()
app.Get("/users/:id", func(c *fiber.Ctx) error {
return c.SendString("User")
}).Name("user.show")
app.Get("/test", func(c *fiber.Ctx) error {
// 生成URL
url, err := app.GetRouteURL("user.show", fiber.Map{
"id": 123,
})
if err != nil {
return err
}
return c.SendString("URL: " + url)
})
app.Listen(":3000")
}
七、路由列表 #
7.1 获取所有路由 #
go
func main() {
app := fiber.New()
app.Get("/", handler)
app.Get("/users", handler)
app.Post("/users", handler)
// 打印所有路由
routes := app.GetRoutes()
for _, route := range routes {
fmt.Printf("%s %s\n", route.Method, route.Path)
}
app.Listen(":3000")
}
7.2 路由信息 #
go
type Route struct {
Method string // HTTP方法
Name string // 路由名称
Path string // 路由路径
Params []string // 参数列表
Handlers []Handler // 处理函数
}
八、路由匹配规则 #
8.1 匹配优先级 #
Fiber按照以下优先级匹配路由:
text
1. 静态路由(/users/list)
2. 动态路由(/users/:id)
3. 通配符路由(/users/*)
go
app.Get("/users/list", func(c *fiber.Ctx) error {
return c.SendString("Static: list")
})
app.Get("/users/:id", func(c *fiber.Ctx) error {
return c.SendString("Dynamic: " + c.Params("id"))
})
app.Get("/users/*", func(c *fiber.Ctx) error {
return c.SendString("Wildcard: " + c.Params("*"))
})
// /users/list → "Static: list"
// /users/123 → "Dynamic: 123"
// /users/a/b/c → "Wildcard: a/b/c"
8.2 路由冲突 #
go
// 错误:参数名冲突
// app.Get("/users/:id", handler)
// app.Get("/users/:name", handler) // 会覆盖前面的路由
// 正确:使用不同的路径
app.Get("/users/id/:id", handler)
app.Get("/users/name/:name", handler)
九、实战示例 #
9.1 RESTful API路由 #
go
func main() {
app := fiber.New()
// 用户资源
users := app.Group("/users")
users.Get("/", listUsers) // 列表
users.Get("/:id", getUser) // 详情
users.Post("/", createUser) // 创建
users.Put("/:id", updateUser) // 更新
users.Delete("/:id", deleteUser) // 删除
// 文章资源
posts := app.Group("/posts")
posts.Get("/", listPosts)
posts.Get("/:id", getPost)
posts.Post("/", createPost)
posts.Put("/:id", updatePost)
posts.Delete("/:id", deletePost)
// 评论资源(嵌套)
posts.Get("/:postId/comments", listComments)
posts.Post("/:postId/comments", createComment)
app.Listen(":3000")
}
9.2 版本化API #
go
func main() {
app := fiber.New()
// v1版本
v1 := app.Group("/v1")
v1.Get("/users", getUsersV1)
v1.Get("/posts", getPostsV1)
// v2版本
v2 := app.Group("/v2")
v2.Get("/users", getUsersV2)
v2.Get("/posts", getPostsV2)
// 默认版本(指向最新)
app.Get("/users", getUsersV2)
app.Listen(":3000")
}
十、总结 #
10.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 路由定义 | app.Get()、app.Post()等方法 |
| 路径参数 | :id 必需参数,:id? 可选参数 |
| 通配符 | * 匹配任意路径 |
| 路由分组 | app.Group() 组织路由 |
| 中间件 | 分组级别应用中间件 |
10.2 下一步 #
现在你已经掌握了路由基础,接下来让我们学习 路由参数,深入了解参数处理!
最后更新:2026-03-28