github.com/gofiber/fiber/v2@v2.47.0/docs/guide/routing.md (about) 1 --- 2 id: routing 3 title: 🔌 Routing 4 description: >- 5 Routing refers to how an application's endpoints (URIs) respond to client 6 requests. 7 sidebar_position: 1 8 --- 9 10 import Tabs from '@theme/Tabs'; 11 import TabItem from '@theme/TabItem'; 12 import RoutingHandler from './../partials/routing/handler.md'; 13 14 ## Handlers 15 16 <RoutingHandler /> 17 18 ## Paths 19 20 Route paths, combined with a request method, define the endpoints at which requests can be made. Route paths can be **strings** or **string patterns**. 21 22 **Examples of route paths based on strings** 23 24 ```go 25 // This route path will match requests to the root route, "/": 26 app.Get("/", func(c *fiber.Ctx) error { 27 return c.SendString("root") 28 }) 29 30 // This route path will match requests to "/about": 31 app.Get("/about", func(c *fiber.Ctx) error { 32 return c.SendString("about") 33 }) 34 35 // This route path will match requests to "/random.txt": 36 app.Get("/random.txt", func(c *fiber.Ctx) error { 37 return c.SendString("random.txt") 38 }) 39 ``` 40 41 As with the expressJs framework, the order of the route declaration plays a role. 42 When a request is received, the routes are checked in the order in which they are declared. 43 44 :::info 45 So please be careful to write routes with variable parameters after the routes that contain fixed parts, so that these variable parts do not match instead and unexpected behavior occurs. 46 ::: 47 48 ## Parameters 49 50 Route parameters are dynamic elements in the route, which are **named** or **not named segments**. This segments that are used to capture the values specified at their position in the URL. The obtained values can be retrieved using the [Params](https://fiber.wiki/context#params) function, with the name of the route parameter specified in the path as their respective keys or for unnamed parameters the character\(\*, +\) and the counter of this. 51 52 The characters :, +, and \* are characters that introduce a parameter. 53 54 Greedy parameters are indicated by wildcard\(\*\) or plus\(+\) signs. 55 56 The routing also offers the possibility to use optional parameters, for the named parameters these are marked with a final "?", unlike the plus sign which is not optional, you can use the wildcard character for a parameter range which is optional and greedy. 57 58 **Example of define routes with route parameters** 59 60 ```go 61 // Parameters 62 app.Get("/user/:name/books/:title", func(c *fiber.Ctx) error { 63 fmt.Fprintf(c, "%s\n", c.Params("name")) 64 fmt.Fprintf(c, "%s\n", c.Params("title")) 65 return nil 66 }) 67 // Plus - greedy - not optional 68 app.Get("/user/+", func(c *fiber.Ctx) error { 69 return c.SendString(c.Params("+")) 70 }) 71 72 // Optional parameter 73 app.Get("/user/:name?", func(c *fiber.Ctx) error { 74 return c.SendString(c.Params("name")) 75 }) 76 77 // Wildcard - greedy - optional 78 app.Get("/user/*", func(c *fiber.Ctx) error { 79 return c.SendString(c.Params("*")) 80 }) 81 82 // This route path will match requests to "/v1/some/resource/name:customVerb", since the parameter character is escaped 83 app.Get("/v1/some/resource/name\\:customVerb", func(c *fiber.Ctx) error { 84 return c.SendString("Hello, Community") 85 }) 86 ``` 87 88 :::info 89 Since the hyphen \(`-`\) and the dot \(`.`\) are interpreted literally, they can be used along with route parameters for useful purposes. 90 ::: 91 92 :::info 93 All special parameter characters can also be escaped with `"\\"` and lose their value, so you can use them in the route if you want, like in the custom methods of the [google api design guide](https://cloud.google.com/apis/design/custom_methods). 94 ::: 95 96 ```go 97 // http://localhost:3000/plantae/prunus.persica 98 app.Get("/plantae/:genus.:species", func(c *fiber.Ctx) error { 99 fmt.Fprintf(c, "%s.%s\n", c.Params("genus"), c.Params("species")) 100 return nil // prunus.persica 101 }) 102 ``` 103 104 ```go 105 // http://localhost:3000/flights/LAX-SFO 106 app.Get("/flights/:from-:to", func(c *fiber.Ctx) error { 107 fmt.Fprintf(c, "%s-%s\n", c.Params("from"), c.Params("to")) 108 return nil // LAX-SFO 109 }) 110 ``` 111 112 Our intelligent router recognizes that the introductory parameter characters should be part of the request route in this case and can process them as such. 113 114 ```go 115 // http://localhost:3000/shop/product/color:blue/size:xs 116 app.Get("/shop/product/color::color/size::size", func(c *fiber.Ctx) error { 117 fmt.Fprintf(c, "%s:%s\n", c.Params("color"), c.Params("size")) 118 return nil // blue:xs 119 }) 120 ``` 121 122 In addition, several parameters in a row and several unnamed parameter characters in the route, such as the wildcard or plus character, are possible, which greatly expands the possibilities of the router for the user. 123 124 ```go 125 // GET /@v1 126 // Params: "sign" -> "@", "param" -> "v1" 127 app.Get("/:sign:param", handler) 128 129 // GET /api-v1 130 // Params: "name" -> "v1" 131 app.Get("/api-:name", handler) 132 133 // GET /customer/v1/cart/proxy 134 // Params: "*1" -> "customer/", "*2" -> "/cart" 135 app.Get("/*v1*/proxy", handler) 136 137 // GET /v1/brand/4/shop/blue/xs 138 // Params: "*1" -> "brand/4", "*2" -> "blue/xs" 139 app.Get("/v1/*/shop/*", handler) 140 ``` 141 142 We have adapted the routing strongly to the express routing, but currently without the possibility of the regular expressions, because they are quite slow. The possibilities can be tested with version 0.1.7 \(express 4\) in the online [Express route tester](http://forbeslindesay.github.io/express-route-tester/). 143 144 ### Constraints 145 Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values by parameters. The feature was intorduced in `v2.37.0` and inspired by [.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-6.0#route-constraints). 146 147 :::caution 148 Constraints aren't validation for parameters. If constraint aren't valid for parameter value, Fiber returns **404 handler**. 149 ::: 150 151 | Constraint | Example | Example matches | 152 | ----------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | 153 | int | :id<int\> | 123456789, -123456789 | 154 | bool | :active<bool\> | true,false | 155 | guid | :id<guid\> | CD2C1638-1638-72D5-1638-DEADBEEF1638 | 156 | float | :weight<float\> | 1.234, -1,001.01e8 | 157 | minLen(value) | :username<minLen(4)\> | Test (must be at least 4 characters) | 158 | maxLen(value) | :filename<maxLen(8)\> | MyFile (must be no more than 8 characters | 159 | len(length) | :filename<len(12)\> | somefile.txt (exactly 12 characters) | 160 | min(value) | :age<min(18)\> | 19 (Integer value must be at least 18) | 161 | max(value) | :age<max(120)\> | 91 (Integer value must be no more than 120) | 162 | range(min,max) | :age<range(18,120)\> | 91 (Integer value must be at least 18 but no more than 120) | 163 | alpha | :name<alpha\> | Rick (String must consist of one or more alphabetical characters, a-z and case-insensitive) | 164 | datetime | :dob<datetime(2006\\\\-01\\\\-02)\> | 2005-11-01 | 165 | regex(expression) | :date<regex(\\d{4}-\\d{2}-\\d{2})}\> | 2022-08-27 (Must match regular expression) | 166 167 **Examples** 168 169 <Tabs> 170 <TabItem value="single-constraint" label="Single Constraint"> 171 172 ```go 173 app.Get("/:test<min(5)>", func(c *fiber.Ctx) error { 174 return c.SendString(c.Params("test")) 175 }) 176 177 // curl -X GET http://localhost:3000/12 178 // 12 179 180 // curl -X GET http://localhost:3000/1 181 // Cannot GET /1 182 ``` 183 </TabItem> 184 <TabItem value="multiple-constraints" label="Multiple Constraints"> 185 186 You can use `;` for multiple constraints. 187 ```go 188 app.Get("/:test<min(100);maxLen(5)>", func(c *fiber.Ctx) error { 189 return c.SendString(c.Params("test")) 190 }) 191 192 // curl -X GET http://localhost:3000/120000 193 // Cannot GET /120000 194 195 // curl -X GET http://localhost:3000/1 196 // Cannot GET /1 197 198 // curl -X GET http://localhost:3000/250 199 // 250 200 ``` 201 </TabItem> 202 <TabItem value="regex-constraint" label="Regex Constraint"> 203 204 Fiber precompiles regex query when to register routes. So there're no performance overhead for regex constraint. 205 ```go 206 app.Get("/:date<regex(\\d{4}-\\d{2}-\\d{2})}>", func(c *fiber.Ctx) error { 207 return c.SendString(c.Params("date")) 208 }) 209 210 // curl -X GET http://localhost:3000/125 211 // Cannot GET /125 212 213 // curl -X GET http://localhost:3000/test 214 // Cannot GET /test 215 216 // curl -X GET http://localhost:3000/2022-08-27 217 // 2022-08-27 218 ``` 219 220 </TabItem> 221 </Tabs> 222 223 :::caution 224 You should use `\\` before routing-specific characters when to use datetime constraint (`*`, `+`, `?`, `:`, `/`, `<`, `>`, `;`, `(`, `)`), to avoid wrong parsing. 225 ::: 226 227 **Optional Parameter Example** 228 229 You can impose constraints on optional parameters as well. 230 231 ```go 232 app.Get("/:test<int>?", func(c *fiber.Ctx) error { 233 return c.SendString(c.Params("test")) 234 }) 235 // curl -X GET http://localhost:3000/42 236 // 42 237 // curl -X GET http://localhost:3000/ 238 // 239 // curl -X GET http://localhost:3000/7.0 240 // Cannot GET /7.0 241 ``` 242 243 ## Middleware 244 245 Functions that are designed to make changes to the request or response are called **middleware functions**. The [Next](../api/ctx.md#next) is a **Fiber** router function, when called, executes the **next** function that **matches** the current route. 246 247 **Example of a middleware function** 248 249 ```go 250 app.Use(func(c *fiber.Ctx) error { 251 // Set a custom header on all responses: 252 c.Set("X-Custom-Header", "Hello, World") 253 254 // Go to next middleware: 255 return c.Next() 256 }) 257 258 app.Get("/", func(c *fiber.Ctx) error { 259 return c.SendString("Hello, World!") 260 }) 261 ``` 262 263 `Use` method path is a **mount**, or **prefix** path, and limits middleware to only apply to any paths requested that begin with it. 264 265 ## Grouping 266 267 If you have many endpoints, you can organize your routes using `Group`. 268 269 ```go 270 func main() { 271 app := fiber.New() 272 273 api := app.Group("/api", middleware) // /api 274 275 v1 := api.Group("/v1", middleware) // /api/v1 276 v1.Get("/list", handler) // /api/v1/list 277 v1.Get("/user", handler) // /api/v1/user 278 279 v2 := api.Group("/v2", middleware) // /api/v2 280 v2.Get("/list", handler) // /api/v2/list 281 v2.Get("/user", handler) // /api/v2/user 282 283 log.Fatal(app.Listen(":3000")) 284 } 285 ``` 286 287 More information about this in our [Grouping Guide](./grouping.md)