跳到主要内容
版本: v2.x

🔌 路由

处理程序

注册绑定到特定 HTTP 方法的路由。

签名
// HTTP methods
func (app *App) Get(path string, handlers ...Handler) Router
func (app *App) Head(path string, handlers ...Handler) Router
func (app *App) Post(path string, handlers ...Handler) Router
func (app *App) Put(path string, handlers ...Handler) Router
func (app *App) Delete(path string, handlers ...Handler) Router
func (app *App) Connect(path string, handlers ...Handler) Router
func (app *App) Options(path string, handlers ...Handler) Router
func (app *App) Trace(path string, handlers ...Handler) Router
func (app *App) Patch(path string, handlers ...Handler) Router

// Add allows you to specifiy a method as value
func (app *App) Add(method, path string, handlers ...Handler) Router

// All will register the route on all HTTP methods
// Almost the same as app.Use but not bound to prefixes
func (app *App) All(path string, handlers ...Handler) Router
示例
// Simple GET handler
app.Get("/api/list", func(c *fiber.Ctx) error {
return c.SendString("I'm a GET request!")
})

// Simple POST handler
app.Post("/api/register", func(c *fiber.Ctx) error {
return c.SendString("I'm a POST request!")
})

Use 可用于中间件包和前缀捕获器。这些路由只匹配每个路径的开头,例如 /john 将匹配 /john/doe/johnnnnn

签名
func (app *App) Use(args ...interface{}) Router
示例
// Match any request
app.Use(func(c *fiber.Ctx) error {
return c.Next()
})

// Match request starting with /api
app.Use("/api", func(c *fiber.Ctx) error {
return c.Next()
})

// Match requests starting with /api or /home (multiple-prefix support)
app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
return c.Next()
})

// Attach multiple handlers
app.Use("/api", func(c *fiber.Ctx) error {
c.Set("X-Custom-Header", random.String(32))
return c.Next()
}, func(c *fiber.Ctx) error {
return c.Next()
})

路径

路由路径与请求方法相结合,定义了可以发出请求的端点。路由路径可以是字符串字符串模式

基于字符串的路由路径示例

// This route path will match requests to the root route, "/":
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("root")
})

// This route path will match requests to "/about":
app.Get("/about", func(c *fiber.Ctx) error {
return c.SendString("about")
})

// This route path will match requests to "/random.txt":
app.Get("/random.txt", func(c *fiber.Ctx) error {
return c.SendString("random.txt")
})

与 expressJs 框架一样,路由声明的顺序很重要。当收到请求时,会按照声明的顺序检查路由。

信息

因此,请注意将带有可变参数的路由写在包含固定部分的路由之后,以免这些可变部分反而匹配,从而导致意外的行为发生。

参数

路由参数是路由中的动态元素,它们是命名未命名的片段。这些片段用于捕获在其 URL 位置指定的值。可以使用 Params 函数获取这些值,其中路径中指定的路由参数名称作为其各自的键,或者对于未命名参数,使用字符(*, +)及其计数器。

字符 :, + 和 * 是引入参数的字符。

贪婪参数由通配符(*)或加号(+)表示。

路由还提供了使用可选参数的可能性,对于命名参数,它们以最终的 "?" 标记,与非可选的加号不同,你可以使用通配符来表示可选且贪婪的参数范围。

定义带路由参数的路由示例

// Parameters
app.Get("/user/:name/books/:title", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s\n", c.Params("name"))
fmt.Fprintf(c, "%s\n", c.Params("title"))
return nil
})
// Plus - greedy - not optional
app.Get("/user/+", func(c *fiber.Ctx) error {
return c.SendString(c.Params("+"))
})

// Optional parameter
app.Get("/user/:name?", func(c *fiber.Ctx) error {
return c.SendString(c.Params("name"))
})

// Wildcard - greedy - optional
app.Get("/user/*", func(c *fiber.Ctx) error {
return c.SendString(c.Params("*"))
})

// This route path will match requests to "/v1/some/resource/name:customVerb", since the parameter character is escaped
app.Get(`/v1/some/resource/name\:customVerb`, func(c *fiber.Ctx) error {
return c.SendString("Hello, Community")
})
信息

由于连字符 (-) 和点 (.) 被字面解释,它们可以与路由参数一起用于有用目的。

信息

所有特殊的参数字符也可以用 "\\" 转义并失去其特殊含义,因此如果你愿意,可以在路由中使用它们,就像 Google API 设计指南中的自定义方法一样。建议使用反引号 `,因为在 go 的正则表达式文档中,他们总是使用反引号来确保清晰无误,并且转义字符不会以意外方式干扰正则表达式模式。

// http://localhost:3000/plantae/prunus.persica
app.Get("/plantae/:genus.:species", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s.%s\n", c.Params("genus"), c.Params("species"))
return nil // prunus.persica
})
// http://localhost:3000/flights/LAX-SFO
app.Get("/flights/:from-:to", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s-%s\n", c.Params("from"), c.Params("to"))
return nil // LAX-SFO
})

我们的智能路由器识别出在这种情况下,引入参数的字符应该作为请求路由的一部分,并可以按此处理它们。

// http://localhost:3000/shop/product/color:blue/size:xs
app.Get("/shop/product/color::color/size::size", func(c *fiber.Ctx) error {
fmt.Fprintf(c, "%s:%s\n", c.Params("color"), c.Params("size"))
return nil // blue:xs
})

此外,路由中可以有多个连续参数和多个未命名参数字符,例如通配符或加号字符,这极大地扩展了路由器的可能性。

// GET /@v1
// Params: "sign" -> "@", "param" -> "v1"
app.Get("/:sign:param", handler)

// GET /api-v1
// Params: "name" -> "v1"
app.Get("/api-:name", handler)

// GET /customer/v1/cart/proxy
// Params: "*1" -> "customer/", "*2" -> "/cart"
app.Get("/*v1*/proxy", handler)

// GET /v1/brand/4/shop/blue/xs
// Params: "*1" -> "brand/4", "*2" -> "blue/xs"
app.Get("/v1/*/shop/*", handler)

我们已将路由功能高度适配 express 路由,但目前暂不支持正则表达式,因为它们速度较慢。可以在在线 Express 路由测试器中使用 0.1.7 版本 (express 4) 测试其可能性。

约束

路由约束在传入 URL 匹配且 URL 路径由参数分解为路由值时执行。该功能在 v2.37.0 中引入,灵感来自 .NET Core

注意

约束不是参数的验证。如果约束对参数值无效,Fiber 将返回 404 处理程序

约束示例示例匹配项
int:id<int\>123456789, -123456789
bool:active<bool\>true,false
guid:id<guid\>CD2C1638-1638-72D5-1638-DEADBEEF1638
float:weight<float\>1.234, -1,001.01e8
minLen(值):username<minLen(4)\>Test (必须至少包含 4 个字符)
maxLen(值):filename<maxLen(8)\>MyFile (必须不超过 8 个字符)
len(长度):filename<len(12)\>somefile.txt (正好 12 个字符)
min(值):age<min(18)\>19 (整数值必须至少为 18)
max(值):age<max(120)\>91 (整数值必须不超过 120)
range(最小值,最大值):age<range(18,120)\>91 (整数值必须至少为 18 但不超过 120)
alpha:name<alpha\>Rick (字符串必须由一个或多个字母字符组成,不区分大小写)
datetime:dob<datetime(2006\\\\-01\\\\-02)\>2005-11-01
regex(表达式):date<regex(\\d{4}-\\d{2}-\\d{2})\>2022-08-27 (必须匹配正则表达式)

示例

app.Get("/:test<min(5)>", func(c *fiber.Ctx) error {
return c.SendString(c.Params("test"))
})

// curl -X GET http://localhost:3000/12
// 12

// curl -X GET http://localhost:3000/1
// Cannot GET /1
注意

在使用 datetime 约束时,应该在路由特定字符 (*, +, ?, :, /, <, >, ;, (, )) 前使用 \\,以避免错误的解析。

可选参数示例

你也可以对可选参数施加约束。

app.Get("/:test<int>?", func(c *fiber.Ctx) error {
return c.SendString(c.Params("test"))
})
// curl -X GET http://localhost:3000/42
// 42
// curl -X GET http://localhost:3000/
//
// curl -X GET http://localhost:3000/7.0
// Cannot GET /7.0

中间件

旨在修改请求或响应的函数称为中间件函数Next 是一个 Fiber 路由器函数,调用时执行匹配当前路由的下一个函数。

中间件函数示例

app.Use(func(c *fiber.Ctx) error {
// Set a custom header on all responses:
c.Set("X-Custom-Header", "Hello, World")

// Go to next middleware:
return c.Next()
})

app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
})

Use 方法路径是挂载前缀路径,它将中间件限制为仅应用于以该路径开头的所有请求路径。

动态添加路由的限制

注意

出于设计和性能方面的考虑,不支持在应用程序启动后动态添加路由。请确保在应用程序启动前定义所有路由。

分组

如果你有许多端点,可以使用 Group 来组织路由。

func main() {
app := fiber.New()

api := app.Group("/api", middleware) // /api

v1 := api.Group("/v1", middleware) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user

v2 := api.Group("/v2", middleware) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user

log.Fatal(app.Listen(":3000"))
}

更多信息请参阅我们的分组指南