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)