Routing
The role of route in the Go Fiber framework is to bind different URLs to handling functions, in order to support HTTP request processing. It serves as the entry point for all web framework requests.
Route Handlers (Functions)
Register routes that are bound to specific HTTP methods.
Note: In some frameworks, route handlers are called controllers, which generally have the same meaning—determining which function (method) to handle the incoming HTTP request.
Function Signature:
// 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 specify methods as values
func (app *App) Add(method, path string, handlers ...Handler) Router
// All registers the route on all HTTP methods
// Similar to app.Use but does not bind a prefix
func (app *App) All(path string, handlers ...Handler) Router
Example:
// Simple GET handler
app.Get("/api/list", func(c *fiber.Ctx) error {
return c.SendString("This is a GET request!")
})
// Simple POST handler
app.Post("/api/register", func(c *fiber.Ctx) error {
return c.SendString("This is a POST request!")
})
Use is used to load middleware and prefix URL interceptors. These routes only match the beginning of each path, for example, /john
will match /john/doe
, /johnnnnn
, and so on.
Custom middleware function signature:
func (app *App) Use(args ...interface{}) Router
Example:
// Match any request
app.Use(func(c *fiber.Ctx) error {
return c.Next()
})
// Match requests starting with /api
app.Use("/api", func(c *fiber.Ctx) error {
return c.Next()
})
// Match requests starting with /api or /home (supports multiple prefixes)
app.Use([]string{"/api", "/home"}, func(c *fiber.Ctx) error {
return c.Next()
})
// Add 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()
})
Path
The route path, together with the request method, defines the endpoints that can be accessed. The route path can be a string or string pattern.
Examples of string-based route paths
// This route path will match requests to the root path, "/":
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Root path")
})
// 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")
Similar to the expressJs framework, the order in which routes are declared is important. When a request is received, the routes are checked in the order they are declared.
Please note:
Ensure that routes with variable parameters are written after routes containing fixed parts to prevent these variable parts from being mistakenly matched, which could lead to unexpected behavior.
Route Parameters
Route parameters are dynamic elements in a route and can be either named or unnamed segments. These segments are used to capture values at specified positions in the URL. You can use the Params function to retrieve these values, where the function parameter is the name of the route parameter in the path, or for unnamed parameters, it is the characters (*, +) and their count.
The wildcard (*) or plus sign (+) represents greedy parameters.
Routes also provide the possibility of using optional parameters. For named parameters, these parameters are followed by a question mark (?), while the plus sign is not optional, and you can use wildcard characters to represent an optional and greedy parameter range.
Example of defining a route with route parameters
// 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 the request "/v1/some/resource/name:customVerb" because the parameter characters have been escaped
app.Get(`/v1/some/resource/name\:customVerb`, func(c *fiber.Ctx) error {
return c.SendString("Hello, Community")
})
As hyphens (-) and periods (.) are interpreted literally, they can be used along with route parameters to achieve useful purposes.
All special parameter characters can also be escaped using
\
and their values will be ignored, so if you want to use them in the route. It is recommended to use backticks ``, as in the Go regular expression documentation they are always used to ensure there is no ambiguity, and the escape characters do not inadvertently affect the regular expression pattern.
// 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
})
Our smart routing recognizes that the introduced parameter characters in this case should be part of the request route and can handle it as such.
// 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
})
In addition, routes can use multiple parameters and multiple unnamed parameter characters consecutively, such as wildcard or plus characters, greatly expanding the possibilities for users in the routes.
// 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)
We have already adapted the routing to Express routing, but it does not yet support regular expressions because they are relatively slow.
Constraints
When there is a match with the incoming URL and the URL path is divided into route values through parameters, the constraints will be executed. This feature was introduced in v2.37.0
and was inspired by .NET Core.
Constraints are not for parameter validation. If the constraint is invalid for the parameter value, Fiber will return a 404 handler.
Constraint | Example | Example Matches |
---|---|---|
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(value) | :username<minLen(4)> | test (at least 4 characters) |
maxLen(value) | :filename<maxLen(8)> | MyFile (up to 8 characters) |
len(length) | :filename<len(12)> | somefile.txt (12 characters) |
min(value) | :age<min(18)> | 19 (integer value must be at least 18) |
max(value) | :age<max(120)> | 91 (integer value cannot exceed 120) |
range(min,max) | :age<range(18,120)> | 91 (integer value must be at least 18 but cannot exceed 120) |
alpha | :name<alpha> | Rick (string must consist of one or more alphabetic characters, case insensitive, a-z) |
datetime | :dob<datetime(2006\\\\-01\\\\-02)> | 2005-11-01 |
regex(expression) | :date<regex(\\d{4}-\\d{2}-\\d{2})> | 2022-08-27 (must match the regular expression) |
Examples
- Single Constraint
- Multiple Constraints
- Regular Expression Constraint
app.Get("/:test", 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 find GET /1
You can use `;` to add multiple constraints.
app.Get(“/:test”, func(c *fiber.Ctx) error {
return c.SendString(c.Params(“test”))
})
// curl -X GET http://localhost:3000/120000
// Cannot find GET /120000
// curl -X GET http://localhost:3000/1
// Cannot find GET /1
// curl -X GET http://localhost:3000/250
// 250
Fiber precompiles regular expression queries when registering routes, so there is no performance overhead for regular expression constraints.
```go
app.Get(`/:date`, func(c *fiber.Ctx) error {
return c.SendString(c.Params("date"))
})
// curl -X GET http://localhost:3000/125
// Cannot find GET /125
// curl -X GET http://localhost:3000/test
// Cannot find GET /test
// curl -X GET http://localhost:3000/2022-08-27
// 2022-08-27
> When using date-time constraints (`*`,`+`,`?`,`:`,`/`,``,``,`>`,';`,`(`,`)`), use `\\` before using special characters in the route to avoid misinterpretation.
**Optional Parameter Example**
You can also add constraints to optional parameters.
```go
app.Get("/:test?", 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 find GET /7.0
Middleware
Functions designed to manipulate requests or responses are called middleware functions. Next
is a Fiber routing function that, when called, executes the next
function that matches the current route.
Middleware Function Example
app.Use(func(c *fiber.Ctx) error {
// Set a custom header in all responses:
c.Set("X-Custom-Header", "Hello, world")
// Proceed to the next middleware:
return c.Next()
})
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, world!")
})
The path for the Use
method can be a mount path or prefix path, and it restricts the middleware to be applied only to requests with paths starting with that path.
Adding Route Limitations at Runtime
Due to design and performance considerations, dynamically adding routes after application startup is not supported. Please ensure that all routes are defined before the application starts.
Grouping
If you have many endpoints, you can use Group
to organize routes.
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"))
}