Skip to main content
Fiber’s routing system provides a powerful and flexible way to define how your application responds to client requests. Routes are matched based on HTTP methods and URL patterns.

Basic Routes

Routes are registered using HTTP method functions on the App instance:
app.Get("/", func(c fiber.Ctx) error {
    return c.SendString("GET request")
})

app.Post("/submit", func(c fiber.Ctx) error {
    return c.SendString("POST request")
})

app.Put("/user/:id", func(c fiber.Ctx) error {
    return c.SendString("PUT request")
})

Route Parameters

Route parameters are dynamic path segments that capture values from the URL. They are defined using the : prefix:
app.Get("/user/:id", func(c fiber.Ctx) error {
    id := c.Params("id")
    return c.SendString("User ID: " + id)
})

// Multiple parameters
app.Get("/posts/:category/:id", func(c fiber.Ctx) error {
    category := c.Params("category")
    id := c.Params("id")
    return c.JSON(fiber.Map{
        "category": category,
        "id":       id,
    })
})

Optional Parameters

Make parameters optional by adding a ? suffix:
app.Get("/user/:id?", func(c fiber.Ctx) error {
    id := c.Params("id", "default-id")
    return c.SendString("User ID: " + id)
})

Wildcard Routes

Wildcard parameters match one or more path segments:

Asterisk Wildcard (*)

The * wildcard is optional and matches zero or more segments:
app.Get("/api/*", func(c fiber.Ctx) error {
    path := c.Params("*")
    return c.SendString("Wildcard: " + path)
})
// Matches: path = "users/123"

Plus Wildcard (+)

The + wildcard is required and matches one or more segments:
app.Get("/files/+", func(c fiber.Ctx) error {
    filepath := c.Params("+")
    return c.SendString("File path: " + filepath)
})
// Matches: filepath = "documents/report.pdf"

Parameter Constraints

Constrain parameter values using type validation:
// Integer constraint
app.Get("/user/:id<int>", func(c fiber.Ctx) error {
    id := c.Params("id")
    return c.SendString("User ID: " + id)
})

// GUID constraint
app.Get("/order/:uuid<guid>", func(c fiber.Ctx) error {
    uuid := c.Params("uuid")
    return c.SendString("Order UUID: " + uuid)
})

// Min/Max length constraints
app.Get("/code/:value<minLen(5);maxLen(10)>", func(c fiber.Ctx) error {
    code := c.Params("value")
    return c.SendString("Code: " + code)
})

// Regex constraint
app.Get("/user/:name<regex(^[a-z]+$)>", func(c fiber.Ctx) error {
    name := c.Params("name")
    return c.SendString("Username: " + name)
})

Available Constraints

ConstraintDescriptionExample
intInteger values:id<int>
boolBoolean values:active<bool>
floatFloat values:price<float>
alphaAlphabetic characters:name<alpha>
guidGUID/UUID format:uuid<guid>
minLen(n)Minimum length:code<minLen(5)>
maxLen(n)Maximum length:code<maxLen(10)>
len(n)Exact length:code<len(8)>
min(n)Minimum value:age<min(18)>
max(n)Maximum value:age<max(100)>
range(min,max)Value range:port<range(1024,65535)>
regex(pattern)Custom regex:slug<regex(^[a-z0-9-]+$)>
datetime(format)Date/time format:date<datetime(2006-01-02)>

Multiple HTTP Methods

Register a route for multiple HTTP methods:
app.Add(["GET", "POST"], "/api/data", func(c fiber.Ctx) error {
    return c.SendString("Handles GET and POST")
})

// All HTTP methods
app.All("/api/catch-all", func(c fiber.Ctx) error {
    return c.SendString("Handles all methods")
})

Named Routes

Assign names to routes for easy reference:
app.Get("/user/:id", handler).Name("user.show")

// Retrieve route by name
route := app.GetRoute("user.show")
fmt.Println(route.Path) // Output: /user/:id

// Use in redirects
app.Get("/profile", func(c fiber.Ctx) error {
    return c.Redirect().Route("user.show", fiber.Map{
        "id": "123",
    })
})

Route Configuration

Control routing behavior with application config:
app := fiber.New(fiber.Config{
    // Case-sensitive routing: /Foo != /foo
    CaseSensitive: true,
    
    // Strict routing: /foo != /foo/
    StrictRouting: true,
    
    // Unescape path values
    UnescapePath: true,
})

Case Sensitivity

By default, routes are case-insensitive:
// Default: CaseSensitive = false
app.Get("/Users", handler)
// Matches: /users, /Users, /USERS

// With CaseSensitive = true
app.Get("/Users", handler)
// Matches: /Users only

Strict Routing

By default, trailing slashes are optional:
// Default: StrictRouting = false
app.Get("/users", handler)
// Matches: /users and /users/

// With StrictRouting = true
app.Get("/users", handler)
// Matches: /users only (not /users/)

Route Matching Order

Routes are matched in the order they are defined. More specific routes should be defined before generic ones:
// Correct order
app.Get("/users/new", newUserHandler)       // Specific
app.Get("/users/:id", showUserHandler)      // Less specific
app.Get("/users/*", catchAllHandler)        // Generic

// If reversed, /users/new would match :id parameter

Route Pattern Matching

Test if a path matches a route pattern without registering the route:
matched := fiber.RoutePatternMatch("/users/123", "/users/:id")
fmt.Println(matched) // Output: true

// With configuration
config := fiber.Config{CaseSensitive: true}
matched = fiber.RoutePatternMatch("/Users", "/users", config)
fmt.Println(matched) // Output: false

Best Practices

Define specific routes before wildcard or parameter routes to ensure correct matching.
app.Get("/api/users/admin", adminHandler)
app.Get("/api/users/:id", userHandler)
app.Get("/api/*", catchAllHandler)
Add constraints to validate parameters early and improve route matching performance.
app.Get("/user/:id<int>", userHandler)
app.Get("/order/:uuid<guid>", orderHandler)
Use named routes for routes that are frequently referenced in redirects or links.
app.Get("/user/:id", userHandler).Name("user.profile")

See Also

Grouping

Organize routes with common prefixes

Middleware

Add logic before/after route handlers

Context

Access request parameters and data

Error Handling

Handle routing errors gracefully

Build docs developers (and LLMs) love