## 1. Project Overview & Quickstart (gofiber/fiber)

## File: README.md

<h1 align="center">
  <a href="https://gofiber.io">
    
      
      
    
  </a>
  
  <a href="https://pkg.go.dev/github.com/gofiber/fiber/v3#pkg-overview">
    
  </a>
  <a href="https://goreportcard.com/report/github.com/gofiber/fiber/v3">
    
  </a>
  <a href="https://codecov.io/gh/gofiber/fiber" >
   
 </a>
  <a href="https://github.com/gofiber/fiber/actions?query=workflow%3ATest">
    
  </a>
  <a href="https://gofiber.github.io/fiber/benchmarks/">
    
  </a>
    <a href="https://docs.gofiber.io">
    
  </a>
  <a href="https://gofiber.io/discord">
    
  </a>
  <a href="https://github.com/sponsors/gofiber">
    
  </a>
</h1>



---







---

## ⚙️ Installation

Fiber requires **Go version `1.26` or higher** to run. If you need to install or upgrade Go, visit the [official Go download page](https://go.dev/dl/). To start setting up your project, create a new directory for your project and navigate into it. Then, initialize your project with Go modules by executing the following command in your terminal:

```bash
go mod init github.com/your/repo
```

To learn more about Go modules and how they work, you can check out the [Using Go Modules](https://go.dev/blog/using-go-modules) blog post.

After setting up your project, you can install Fiber with the `go get` command:

```bash
go get -u github.com/gofiber/fiber/v3
```

This command fetches the Fiber package and adds it to your project's dependencies, allowing you to start building your web applications with Fiber.

## ⚡️ Quickstart

Getting started with Fiber is easy. Here's a basic example to create a simple web server that responds with "Hello, World 👋!" on the root path. This example demonstrates initializing a new Fiber app, setting up a route, and starting the server.

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
)

func main() {
    // Initialize a new Fiber app
    app := fiber.New()

    // Define a route for the GET method on the root path '/'
    app.Get("/", func(c fiber.Ctx) error {
        // Send a string response to the client
        return c.SendString("Hello, World 👋!")
    })

    // Start the server on port 3000
    log.Fatal(app.Listen(":3000"))
}
```

This simple server is easy to set up and run. It introduces the core concepts of Fiber: app initialization, route definition, and starting the server. Just run this Go program, and visit `http://localhost:3000` in your browser to see the message.

## Zero Allocation

Fiber is optimized for **high-performance**, meaning values returned from **fiber.Ctx** are **not** immutable by default and **will** be reused across requests. As a rule of thumb, you **must** only use context values within the handler and **must not** keep any references. Once you return from the handler, any values obtained from the context will be reused in future requests. Visit our [documentation](https://docs.gofiber.io/#zero-allocation) to learn more.

## 🤖 Benchmarks

These tests are performed by [TechEmpower](https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=plaintext). If you want to see all the results, please visit our [Wiki](https://docs.gofiber.io/extra/benchmarks).


  
  


## 🎯 Features

- Robust [Routing](https://docs.gofiber.io/guide/routing)
- Serve [Static Files](https://docs.gofiber.io/api/app#static)
- Extreme [Performance](https://docs.gofiber.io/extra/benchmarks)
- [Low Memory](https://docs.gofiber.io/extra/benchmarks) footprint
- [API Endpoints](https://docs.gofiber.io/api/ctx)
- [Middleware](https://docs.gofiber.io/category/-middleware) & [Next](https://docs.gofiber.io/api/ctx#next) support
- [Rapid](https://dev.to/koddr/welcome-to-fiber-an-express-js-styled-fastest-web-framework-written-with-on-golang-497) server-side programming
- [Template Engines](https://github.com/gofiber/template)
- [WebSocket Support](https://docs.gofiber.io/contrib/websocket)
- [Socket.io Support](https://docs.gofiber.io/contrib/socketio)
- [Server-Sent Events](https://docs.gofiber.io/middleware/sse)
- [Rate Limiter](https://docs.gofiber.io/middleware/limiter)
- And much more, [explore Fiber](https://docs.gofiber.io/)

## 💡 Philosophy

New gophers that make the switch from [Node.js](https://nodejs.org/en/about/) to [Go](https://go.dev/doc/) are dealing with a learning curve before they can start building their web applications or microservices. Fiber, as a **web framework**, was created with the idea of **minimalism** and follows the **UNIX way**, so that new gophers can quickly enter the world of Go with a warm and trusted welcome.

Fiber is **inspired** by Express, the most popular web framework on the Internet. We combined the **ease** of Express and **raw performance** of Go. If you have ever implemented a web application in Node.js (_using Express or similar_), then many methods and principles will seem **very common** to you.

We **listen** to our users in [issues](https://github.com/gofiber/fiber/issues), Discord [channel](https://gofiber.io/discord) _and all over the Internet_ to create a **fast**, **flexible** and **friendly** Go web framework for **any** task, **deadline** and developer **skill**! Just like Express does in the JavaScript world.

## ⚠️ Limitations

- Due to Fiber's usage of unsafe, the library may not always be compatible with the latest Go version. Fiber v3 has been tested with Go version 1.26 or higher.
- Fiber automatically adapts common `net/http` handler shapes when you register them on the router, and you can still use the [adaptor middleware](https://docs.gofiber.io/middleware/adaptor/) when you need to bridge entire apps or `net/http` middleware.

### net/http compatibility

Fiber can run side by side with the standard library. The router accepts existing `net/http` handlers directly and even works with native `fasthttp.RequestHandler` callbacks, so you can plug in legacy endpoints without wrapping them manually:

```go
package main

import (
    "log"
    "net/http"

    "github.com/gofiber/fiber/v3"
)

func main() {
    httpHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if _, err := w.Write([]byte("served by net/http")); err != nil {
            panic(err)
        }
    })

    app := fiber.New()
    app.Get("/", httpHandler)

    // Start the server on port 3000
    log.Fatal(app.Listen(":3000"))
}
```

When you need to convert entire applications or reuse `net/http` middleware chains, rely on the [adaptor middleware](https://docs.gofiber.io/middleware/adaptor/). It converts handlers and middlewares in both directions and even lets you mount a Fiber app in a `net/http` server.

### Express-style handlers

Fiber also adapts Express-style callbacks that operate on the lightweight `fiber.Req` and `fiber.Res` helper interfaces. This lets you port middleware and route handlers from Express-inspired codebases while keeping Fiber's router features:

```go
// Request/response handlers (2-argument)
app.Get("/", func(req fiber.Req, res fiber.Res) error {
    return res.SendString("Hello from Express-style handlers!")
})

// Middleware with an error-returning next callback (3-argument)
app.Use(func(req fiber.Req, res fiber.Res, next func() error) error {
    if req.IP() == "192.168.1.254" {
        return res.SendStatus(fiber.StatusForbidden)
    }
    return next()
})

// Middleware with a no-arg next callback (3-argument)
app.Use(func(req fiber.Req, res fiber.Res, next func()) {
    if req.Get("X-Skip") == "true" {
        return // stop the chain without calling next
    }
    next()
})
```

> **Note:** Adapted `net/http` handlers continue to operate with the standard-library semantics. They don't get access to `fiber.Ctx` features and incur the overhead of the compatibility layer, so native `fiber.Handler` callbacks still provide the best performance.

## 👀 Examples

Listed below are some of the common examples. If you want to see more code examples, please visit our [Recipes repository](https://github.com/gofiber/recipes) or visit our hosted [API documentation](https://docs.gofiber.io).

### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)

```go title="Example"
package main

import (
    "fmt"
    "log"

    "github.com/gofiber/fiber/v3"
)

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

    // GET /api/register
    app.Get("/api/*", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("✋ %s", c.Params("*"))
        return c.SendString(msg) // => ✋ register
    })

    // GET /flights/LAX-SFO
    app.Get("/flights/:from-:to", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
        return c.SendString(msg) // => 💸 From: LAX, To: SFO
    })

    // GET /dictionary.txt
    app.Get("/:file.:ext", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
        return c.SendString(msg) // => 📃 dictionary.txt
    })

    // GET /john/75
    app.Get("/:name/:age/:gender?", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
        return c.SendString(msg) // => 👴 john is 75 years old
    })

    // GET /john
    app.Get("/:name", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
        return c.SendString(msg) // => Hello john 👋!
    })

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

#### 📖 [**Route Naming**](https://docs.gofiber.io/api/app#name)

```go title="Example"
package main

import (
    "encoding/json"
    "fmt"
    "log"

    "github.com/gofiber/fiber/v3"
)

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

    app.Get("/api/*", func(c fiber.Ctx) error {
        msg := fmt.Sprintf("✋ %s", c.Params("*"))
        return c.SendString(msg) // => ✋ register
    }).Name("api")

    route := app.GetRoute("api")

    data, _ := json.MarshalIndent(route, "", "  ")
    fmt.Println(string(data))
    // Prints:
    // {
    //    "method": "GET",
    //    "name": "api",
    //    "path": "/api/*",
    //    "params": [
    //      "*1"
    //    ]
    // }

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

#### 📖 [**Serving Static Files**](https://docs.gofiber.io/api/app#static)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/static"
)

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

    // Serve static files from the "./public" directory
    app.Get("/*", static.New("./public"))
    // => http://localhost:3000/js/script.js
    // => http://localhost:3000/css/style.css

    app.Get("/prefix*", static.New("./public"))
    // => http://localhost:3000/prefix/js/script.js
    // => http://localhost:3000/prefix/css/style.css

    // Serve a single file for any unmatched routes
    app.Get("*", static.New("./public/index.html"))
    // => http://localhost:3000/any/path/shows/index.html

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

#### 📖 [**Middleware & Next**](https://docs.gofiber.io/api/ctx#next)

```go title="Example"
package main

import (
    "fmt"
    "log"

    "github.com/gofiber/fiber/v3"
)

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

    // Middleware that matches any route
    app.Use(func(c fiber.Ctx) error {
        fmt.Println("🥇 First handler")
        return c.Next()
    })

    // Middleware that matches all routes starting with /api
    app.Use("/api", func(c fiber.Ctx) error {
        fmt.Println("🥈 Second handler")
        return c.Next()
    })

    // GET /api/list
    app.Get("/api/list", func(c fiber.Ctx) error {
        fmt.Println("🥉 Last handler")
        return c.SendString("Hello, World 👋!")
    })

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


  📚 Show more code examples

### Views Engines

📖 [Config](https://docs.gofiber.io/api/fiber#config)
📖 [Engines](https://github.com/gofiber/template)
📖 [Render](https://docs.gofiber.io/api/ctx#render)

Fiber defaults to the [html/template](https://pkg.go.dev/html/template/) when no view engine is set.

If you want to execute partials or use a different engine like [amber](https://github.com/eknkc/amber), [handlebars](https://github.com/aymerick/raymond), [mustache](https://github.com/cbroglie/mustache), or [pug](https://github.com/Joker/jade), etc., check out our [Template](https://github.com/gofiber/template) package that supports multiple view engines.

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/template/pug"
)

func main() {
    // Initialize a new Fiber app with Pug template engine
    app := fiber.New(fiber.Config{
        Views: pug.New("./views", ".pug"),
    })

    // Define a route that renders the "home.pug" template
    app.Get("/", func(c fiber.Ctx) error {
        return c.Render("home", fiber.Map{
            "title": "Homepage",
            "year":  1999,
        })
    })

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

### Grouping Routes into Chains

📖 [Group](https://docs.gofiber.io/api/app#group)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
)

func middleware(c fiber.Ctx) error {
    log.Println("Middleware executed")
    return c.Next()
}

func handler(c fiber.Ctx) error {
    return c.SendString("Handler response")
}

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

    // Root API group with middleware
    api := app.Group("/api", middleware) // /api

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

    // API v2 routes
    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"))
}
```

### Middleware Logger

📖 [Logger](https://docs.gofiber.io/middleware/logger)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/logger"
)

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

    // Use Logger middleware
    app.Use(logger.New())

    // Define routes
    app.Get("/", func(c fiber.Ctx) error {
        return c.SendString("Hello, Logger!")
    })

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

### Cross-Origin Resource Sharing (CORS)

📖 [CORS](https://docs.gofiber.io/middleware/cors)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/cors"
)

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

    // Use CORS middleware with default settings
    app.Use(cors.New())

    // Define routes
    app.Get("/", func(c fiber.Ctx) error {
        return c.SendString("CORS enabled!")
    })

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

Check CORS by passing any domain in `Origin` header:

```bash
curl -H "Origin: http://example.com" --verbose http://localhost:3000
```

### Custom 404 Response

📖 [HTTP Methods](https://docs.gofiber.io/api/ctx#status)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
)

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

    // Define routes
    app.Get("/", static.New("./public"))

    app.Get("/demo", func(c fiber.Ctx) error {
        return c.SendString("This is a demo page!")
    })

    app.Post("/register", func(c fiber.Ctx) error {
        return c.SendString("Registration successful!")
    })

    // Middleware to handle 404 Not Found
    app.Use(func(c fiber.Ctx) error {
        return c.SendStatus(fiber.StatusNotFound) // => 404 "Not Found"
    })

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

### JSON Response

📖 [JSON](https://docs.gofiber.io/api/ctx#json)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
)

type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

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

    // Route that returns a JSON object
    app.Get("/user", func(c fiber.Ctx) error {
        return c.JSON(&User{"John", 20})
        // => {"name":"John", "age":20}
    })

    // Route that returns a JSON map
    app.Get("/json", func(c fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "success": true,
            "message": "Hi John!",
        })
        // => {"success":true, "message":"Hi John!"}
    })

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

### WebSocket Upgrade

📖 [Websocket](https://docs.gofiber.io/contrib/websocket)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/websocket"
)

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

    // WebSocket route
    app.Get("/ws", websocket.New(func(c *websocket.Conn) {
        defer c.Close()
        for {
            // Read message from client
            mt, msg, err := c.ReadMessage()
            if err != nil {
                log.Println("read:", err)
                break
            }
            log.Printf("recv: %s", msg)

            // Write message back to client
            err = c.WriteMessage(mt, msg)
            if err != nil {
                log.Println("write:", err)
                break
            }
        }
    }))

    log.Fatal(app.Listen(":3000"))
    // Connect via WebSocket at ws://localhost:3000/ws
}
```

### Server-Sent Events

📖 [More Info](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)

```go title="Example"
package main

import (
    "bufio"
    "fmt"
    "log"
    "time"

    "github.com/gofiber/fiber/v3"
    "github.com/valyala/fasthttp"
)

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

    // Server-Sent Events route
    app.Get("/sse", func(c fiber.Ctx) error {
        c.Set("Content-Type", "text/event-stream")
        c.Set("Cache-Control", "no-cache")
        c.Set("Connection", "keep-alive")
        c.Set("Transfer-Encoding", "chunked")

        c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
            var i int
            for {
                i++
                msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
                fmt.Fprintf(w, "data: Message: %s\n\n", msg)
                fmt.Println(msg)

                w.Flush()
                time.Sleep(5 * time.Second)
            }
        })

        return nil
    })

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

### Recover Middleware

📖 [Recover](https://docs.gofiber.io/middleware/recover)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/recover"
)

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

    // Use Recover middleware to handle panics gracefully
    app.Use(recover.New())

    // Route that intentionally panics
    app.Get("/", func(c fiber.Ctx) error {
        panic("normally this would crash your app")
    })

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

### Using Trusted Proxy

📖 [Config](https://docs.gofiber.io/api/fiber#config)

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
)

func main() {
    app := fiber.New(fiber.Config{
        // Configure trusted proxies - WARNING: Only trust proxies you control
        // Using TrustProxy: true with unrestricted IPs can lead to IP spoofing
        TrustProxy: true,
        TrustProxyConfig: fiber.TrustProxyConfig{
            Proxies: []string{"10.0.0.0/8", "172.16.0.0/12"}, // Example: Internal network ranges only
        },
        ProxyHeader: fiber.HeaderXForwardedFor,
    })

    // Define routes
    app.Get("/", func(c fiber.Ctx) error {
        return c.SendString("Trusted Proxy Configured!")
    })

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



## 🧬 Internal Middleware

Here is a list of middleware that are included within the Fiber framework.

| Middleware                                                                           | Description                                                                                                                                                             |
|--------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [adaptor](https://github.com/gofiber/fiber/tree/main/middleware/adaptor)             | Converter for net/http handlers to/from Fiber request handlers.                                                                                                         |
| [basicauth](https://github.com/gofiber/fiber/tree/main/middleware/basicauth)         | Provides HTTP basic authentication. It calls the next handler for valid credentials and 401 Unauthorized for missing or invalid credentials.                            |
| [cache](https://github.com/gofiber/fiber/tree/main/middleware/cache)                 | Intercept and cache HTTP responses.                                                                                                                                     |
| [compress](https://github.com/gofiber/fiber/tree/main/middleware/compress)           | Compression middleware for Fiber, with support for `deflate`, `gzip`, `brotli` and `zstd`.                                                                             |
| [cors](https://github.com/gofiber/fiber/tree/main/middleware/cors)                   | Enable cross-origin resource sharing (CORS) with various options.                                                                                                       |
| [csrf](https://github.com/gofiber/fiber/tree/main/middleware/csrf)                   | Protect from CSRF exploits.                                                                                                                                             |
| [earlydata](https://github.com/gofiber/fiber/tree/main/middleware/earlydata)         | Adds support for TLS 1.3's early data ("0-RTT") feature.                                                                                                                |
| [encryptcookie](https://github.com/gofiber/fiber/tree/main/middleware/encryptcookie) | Encrypt middleware which encrypts cookie values.                                                                                                                        |
| [envvar](https://github.com/gofiber/fiber/tree/main/middleware/envvar)               | Expose environment variables with providing an optional config.                                                                                                         |
| [etag](https://github.com/gofiber/fiber/tree/main/middleware/etag)                   | Allows for caches to be more efficient and save bandwidth, as a web server does not need to resend a full response if the content has not changed.                      |
| [expvar](https://github.com/gofiber/fiber/tree/main/middleware/expvar)               | Serves via its HTTP server runtime exposed variables in the JSON format.                                                                                                 |
| [favicon](https://github.com/gofiber/fiber/tree/main/middleware/favicon)             | Ignore favicon from logs or serve from memory if a file path is provided.                                                                                               |
| [healthcheck](https://github.com/gofiber/fiber/tree/main/middleware/healthcheck)     | Liveness and Readiness probes for Fiber.                                                                                                                                |
| [helmet](https://github.com/gofiber/fiber/tree/main/middleware/helmet)               | Helps secure your apps by setting various HTTP headers.                                                                                                                 |
| [hostauthorization](https://github.com/gofiber/fiber/tree/main/middleware/hostauthorization) | Validates the Host header against a configurable allowlist, protecting against DNS rebinding attacks.                                                            |
| [idempotency](https://github.com/gofiber/fiber/tree/main/middleware/idempotency)     | Allows for fault-tolerant APIs where duplicate requests do not erroneously cause the same action performed multiple times on the server-side.                           |
| [keyauth](https://github.com/gofiber/fiber/tree/main/middleware/keyauth)             | Adds support for key based authentication.                                                                                                                              |
| [limiter](https://github.com/gofiber/fiber/tree/main/middleware/limiter)             | Adds Rate-limiting support to Fiber. Use to limit repeated requests to public APIs and/or endpoints such as password reset.                                             |
| [logger](https://github.com/gofiber/fiber/tree/main/middleware/logger)               | HTTP request/response logger.                                                                                                                                           |
| [paginate](https://github.com/gofiber/fiber/tree/main/middleware/paginate)           | Extracts pagination parameters from query strings. Supports page-based, offset-based, and cursor-based pagination with multi-field sorting.                             |
| [pprof](https://github.com/gofiber/fiber/tree/main/middleware/pprof)                 | Serves runtime profiling data in pprof format.                                                                                                                          |
| [proxy](https://github.com/gofiber/fiber/tree/main/middleware/proxy)                 | Allows you to proxy requests to multiple servers.                                                                                                                       |
| [recover](https://github.com/gofiber/fiber/tree/main/middleware/recover)             | Recovers from panics anywhere in the stack chain and handles the control to the centralized ErrorHandler.                                                               |
| [redirect](https://github.com/gofiber/fiber/tree/main/middleware/redirect)           | Redirect middleware.                                                                                                                                                    |
| [requestid](https://github.com/gofiber/fiber/tree/main/middleware/requestid)         | Adds a request ID to every request.                                                                                                                                     |
| [responsetime](https://github.com/gofiber/fiber/tree/main/middleware/responsetime)   | Measures request handling duration and writes it to a configurable response header.                          |
| [rewrite](https://github.com/gofiber/fiber/tree/main/middleware/rewrite)             | Rewrites the URL path based on provided rules. It can be helpful for backward compatibility or just creating cleaner and more descriptive links.                        |
| [session](https://github.com/gofiber/fiber/tree/main/middleware/session)             | Session middleware. NOTE: This middleware uses our Storage package.                                                                                                     |
| [skip](https://github.com/gofiber/fiber/tree/main/middleware/skip)                   | Skip middleware that skips a wrapped handler if a predicate is true.                                                                                                    |
| [static](https://github.com/gofiber/fiber/tree/main/middleware/static)               | Static middleware for Fiber that serves static files such as **images**, **CSS**, and **JavaScript**.                                                                    |
| [timeout](https://github.com/gofiber/fiber/tree/main/middleware/timeout)             | Adds a max time for a request and forwards to ErrorHandler if it is exceeded.                                                                                           |

## 🧬 External Middleware

List of externally hosted middleware modules and maintained by the [Fiber team](https://github.com/orgs/gofiber/people).

| Middleware                                        | Description                                                                                                           |
| :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------- |
| [contrib](https://github.com/gofiber/contrib)   | Third-party middlewares                                                                                               |
| [storage](https://github.com/gofiber/storage)   | Premade storage drivers that implement the Storage interface, designed to be used with various Fiber middlewares.     |
| [template](https://github.com/gofiber/template) | This package contains 9 template engines that can be used with Fiber.      |

## 🕶️ Awesome List

For more articles, middlewares, examples, or tools, check our [awesome list](https://github.com/gofiber/awesome-fiber).

## 👍 Contribute

If you want to say **Thank You** and/or support the active development of `Fiber`:

1. Add a [GitHub Star](https://github.com/gofiber/fiber#%EF%B8%8F-stargazers) to the project.
2. Tweet about the project [on your 𝕏 (Twitter)](https://x.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
3. Write a review or tutorial on [Medium](https://medium.com/), [Dev.to](https://dev.to/) or your personal blog.
4. Support the project by becoming a [GitHub Sponsor](https://github.com/sponsors/gofiber).

## 💻 Development

To ensure your contributions are ready for a Pull Request, please use the following `Makefile` commands. These tools help maintain code quality and consistency.

- **make help**: Display available commands.
- **make audit**: Conduct quality checks.
- **make benchmark**: Benchmark code performance.
- **make coverage**: Generate test coverage report.
- **make format**: Automatically format code.
- **make lint**: Run lint checks.
- **make test**: Execute all tests.
- **make tidy**: Tidy dependencies.

Run these commands to ensure your code adheres to project standards and best practices.


## ☕ Supporters

Fiber is an open-source project that runs on donations to pay the bills, e.g., our domain name, GitBook, Netlify, and serverless hosting. If you want to support Fiber, please sponsor the organization via ⭐ [**GitHub Sponsors**](https://github.com/sponsors/gofiber).



### 📅 Monthly Sponsors



| **🔥 Fiber Guardian** | [](https://www.coderabbit.ai/?utm_source=cr_org&amp;utm_medium=github) |
| --- | --- |
| **☕ Fiber Supporter** | [](https://ndole.studio) |
| **🪴 Fiber Friend** | [](https://github.com/simonheisstpeter) |



### 🎁 One-time Sponsors



| **🚀 Fiber Hero** | [](https://www.thanks.dev) |
| --- | --- |
| **🪴 Fiber Friend** | [](https://github.com/Gl1tchedPixzl) |





## 💻 Code Contributors

<a href="https://github.com/gofiber/fiber/graphs/contributors">
  
</a>

## ⭐️ Stargazers


  
  
  


## 🧾 License

Copyright (c) 2019-present [Fenny](https://github.com/fenny) and [Contributors](https://github.com/gofiber/fiber/graphs/contributors). `Fiber` is free and open-source software licensed under the [MIT License](https://github.com/gofiber/fiber/blob/main/LICENSE). Official logo was created by [Vic Shóstak](https://github.com/koddr) and distributed under [Creative Commons](https://creativecommons.org/licenses/by-sa/4.0/) license (CC BY-SA 4.0 International).

---

## File: addon/retry/README.md

# Retry Addon

Retry addon for [Fiber](https://github.com/gofiber/fiber) designed to apply retry mechanism for unsuccessful network
operations. This addon uses an exponential backoff algorithm with jitter. It calls the function multiple times and tries
to make it successful. If all calls are failed, then, it returns an error. It adds a jitter at each retry step because adding
a jitter is a way to break synchronization across the client and avoid collision.

## Table of Contents

- [Retry Addon](#retry-addon)
- [Table of Contents](#table-of-contents)
- [Signatures](#signatures)
- [Examples](#examples)
- [Default Config](#default-config)
- [Custom Config](#custom-config)
- [Config](#config)
- [Default Config Example](#default-config-example)

## Signatures

```go
func NewExponentialBackoff(config ...retry.Config) *retry.ExponentialBackoff
```

## Examples

```go
package main

import (
    "fmt"

    "github.com/gofiber/fiber/v3/addon/retry"
    "github.com/gofiber/fiber/v3/client"
)

func main() {
    expBackoff := retry.NewExponentialBackoff(retry.Config{})

    // Local variables that will be used inside of Retry
    var resp *client.Response
    var err error

    // Retry a network request and return an error to signify to try again
    err = expBackoff.Retry(func() error {
        client := client.New()
        resp, err = client.Get("https://gofiber.io")
        if err != nil {
            return fmt.Errorf("GET gofiber.io failed: %w", err)
        }
        if resp.StatusCode() != 200 {
            return fmt.Errorf("GET gofiber.io did not return OK 200")
        }
        return nil
    })

    // If all retries failed, panic
    if err != nil {
        panic(err)
    }
    fmt.Printf("GET gofiber.io succeeded with status code %d\n", resp.StatusCode())
}
```

## Default Config

```go
retry.NewExponentialBackoff()
```

## Custom Config

```go
retry.NewExponentialBackoff(retry.Config{
    InitialInterval: 2 * time.Second,
    MaxBackoffTime:  64 * time.Second,
    Multiplier:      2.0,
    MaxRetryCount:   15,
})
```

## Config

```go
// Config defines the config for addon.
type Config struct {
    // InitialInterval defines the initial time interval for backoff algorithm.
    //
    // Optional. Default: 1 * time.Second
    InitialInterval time.Duration

    // MaxBackoffTime defines maximum time duration for backoff algorithm. When
    // the algorithm is reached this time, rest of the retries will be maximum
    // 32 seconds.
    //
    // Optional. Default: 32 * time.Second
    MaxBackoffTime time.Duration

    // Multiplier defines multiplier number of the backoff algorithm.
    //
    // Optional. Default: 2.0
    Multiplier float64

    // MaxRetryCount defines maximum retry count for the backoff algorithm.
    //
    // Optional. Default: 10
    MaxRetryCount int
}
```

## Default Config Example

```go
// DefaultConfig is the default config for retry.
var DefaultConfig = Config{
    InitialInterval: 1 * time.Second,
    MaxBackoffTime:  32 * time.Second,
    Multiplier:      2.0,
    MaxRetryCount:   10,
    currentInterval: 1 * time.Second,
}
```

Every `Retry` call starts over at `InitialInterval` and keeps its backoff state to itself, so one `ExponentialBackoff` can be shared by concurrent callers.

---

## File: binder/README.md

# Fiber Binders

**Binder** is a new request/response binding feature for Fiber introduced in Fiber v3. It replaces the old Fiber parsers and offers enhanced capabilities such as custom binder registration, struct validation, support for `map[string]string`, `map[string][]string`, and more. Binder replaces the following components:

- `BodyParser`
- `ParamsParser`
- `GetReqHeaders`
- `GetRespHeaders`
- `AllParams`
- `QueryParser`
- `ReqHeaderParser`

## Default Binders

Fiber provides several default binders out of the box:

- [Form](form.go)
- [Query](query.go)
- [URI](uri.go)
- [Header](header.go)
- [Response Header](resp_header.go)
- [Cookie](cookie.go)
- [JSON](json.go)
- [XML](xml.go)
- [CBOR](cbor.go)

## Guides

### Binding into a Struct

Fiber supports binding request data directly into a struct using [gofiber/schema](https://github.com/gofiber/schema). Here's an example:

```go
// Field names must start with an uppercase letter
type Person struct {
    Name string `json:"name" xml:"name" form:"name"`
    Pass string `json:"pass" xml:"pass" form:"pass"`
}

app.Post("/", func(c fiber.Ctx) error {
    p := new(Person)

    if err := c.Bind().Body(p); err != nil {
        return err
    }

    log.Println(p.Name) // Output: john
    log.Println(p.Pass) // Output: doe

    // Additional logic...
})

// Run tests with the following curl commands:

// JSON
curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000

// XML
curl -X POST -H "Content-Type: application/xml" --data "<login><name>john</name>doe</login>" localhost:3000

// URL-Encoded Form
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000

// Multipart Form
curl -X POST -F name=john -F pass=doe http://localhost:3000

// Query Parameters
curl -X POST "http://localhost:3000/?name=john&pass=doe"
```

### Binding into a Map

Fiber allows binding request data into a `map[string]string` or `map[string][]string`. Here's an example:

```go
app.Get("/", func(c fiber.Ctx) error {
    params := make(map[string][]string)

    if err := c.Bind().Query(params); err != nil {
        return err
    }

    log.Println(params["name"])     // Output: [john]
    log.Println(params["pass"])     // Output: [doe]
    log.Println(params["products"]) // Output: [shoe hat]

    // Additional logic...
    return nil
})

// Run tests with the following curl command:

curl "http://localhost:3000/?name=john&pass=doe&products=shoe&products=hat"
```

### Automatic Error Handling with `WithAutoHandling`

By default, Fiber returns binder errors directly. To handle errors automatically and return a `400 Bad Request` status, use the `WithAutoHandling()` method.

**Example:**

```go
// Field names must start with an uppercase letter
type Person struct {
    Name string `json:"name,required"`
    Pass string `json:"pass"`
}

app.Get("/", func(c fiber.Ctx) error {
    p := new(Person)

    if err := c.Bind().WithAutoHandling().JSON(p); err != nil {
        return err 
        // Automatically returns status code 400
        // Response: Bad request: name is empty
    }

    // Additional logic...
    return nil
})

// Run tests with the following curl command:

curl -X GET -H "Content-Type: application/json" --data "{\"pass\":\"doe\"}" localhost:3000
```

### Defining a Custom Binder

Fiber maintains a minimal codebase by not including every possible binder. If you need to use a custom binder, you can easily register and utilize it. Here's an example of creating a `toml` binder.

```go
type Person struct {
    Name string `toml:"name"`
    Pass string `toml:"pass"`
}

type tomlBinding struct{}

func (b *tomlBinding) Name() string {
    return "toml"
}

func (b *tomlBinding) MIMETypes() []string {
    return []string{"application/toml"}
}

func (b *tomlBinding) Parse(c fiber.Ctx, out any) error {
    return toml.Unmarshal(c.Body(), out)
}

func main() {
    app := fiber.New()
    app.RegisterCustomBinder(&tomlBinding{})

    app.Get("/", func(c fiber.Ctx) error {
        out := new(Person)
        if err := c.Bind().Body(out); err != nil {
            return err
        }

        // Alternatively, specify the custom binder:
        // if err := c.Bind().Custom("toml", out); err != nil {
        //     return err
        // }

        return c.SendString(out.Pass) // Output: test
    })

    app.Listen(":3000")
}

// Run tests with the following curl command:

curl -X GET -H "Content-Type: application/toml" --data "name = 'bar'
pass = 'test'" localhost:3000
```

### Defining a Custom Validator

All Fiber binders support struct validation if a validator is defined in the configuration. You can create your own validator or use existing ones like [go-playground/validator](https://github.com/go-playground/validator) or [go-ozzo/ozzo-validation](https://github.com/go-ozzo/ozzo-validation). Here's an example of a simple custom validator:

```go
type Query struct {
    Name string `query:"name"`
}

type structValidator struct{}

func (v *structValidator) Engine() any {
    return nil // Implement if using an external validation engine
}

func (v *structValidator) ValidateStruct(out any) error {
    data := reflect.ValueOf(out).Elem().Interface()
    query := data.(Query)

    if query.Name != "john" {
        return errors.New("you should have entered the correct name!")
    }

    return nil
}

func main() {
    app := fiber.New(fiber.Config{
        StructValidator: &structValidator{},
    })

    app.Get("/", func(c fiber.Ctx) error {
        out := new(Query)
        if err := c.Bind().Query(out); err != nil {
            return err // Returns: you should have entered the correct name!
        }
        return c.SendString(out.Name)
    })

    app.Listen(":3000")
}

// Run tests with the following curl command:

curl "http://localhost:3000/?name=efe"
```

---

## File: client/README.md

<h1 align="center">Fiber Client</h1>



## Features

> The characteristics have not yet been written.

- GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS, etc.
- Simple and chainable methods for settings and request
- Request Body can be `string`, `[]byte`, `map`, `slice`
  - Auto detects `Content-Type`
  - Buffer processing for `files`
  - Native `*fasthttp.Request` instance can be accessed during middleware and request execution via `Request.RawRequest`
  - Request Body can be read multiple time via `Request.RawRequest.GetBody()`
- Response object gives you more possibility
  - Access as `[]byte` by `response.Body()` or access as `string` by `response.String()`
- Automatic marshal and unmarshal for JSON and XML content type
  - Default is JSON, if you supply struct/map without header Content-Type
  - For auto-unmarshal, refer to -
    - Success scenario Request.SetResult() and Response.Result().
    - Error scenario Request.SetError() and Response.Error().
    - Supports RFC7807 - application/problem+json & application/problem+xml
  - Provide an option to override JSON Marshal/Unmarshal and XML Marshal/Unmarshal

## Usage

The following samples will assist you to become as comfortable as possible with `Fiber Client` library.

```go
// Import Fiber Client into your code and refer it as `client`.
import "github.com/gofiber/fiber/client"
```

### Simple GET

---

## File: docs/guide/error-handling.md

---
id: error-handling
title: 🐛 Error Handling
  Fiber supports centralized error handling: handlers return errors so you can
  log them or send a custom HTTP response to the client.
sidebar_position: 4
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

## Catching Errors

Return errors from route handlers and middleware so Fiber can handle them centrally.

<Tabs>
<TabItem value="example" label="Example">

```go
app.Get("/", func(c fiber.Ctx) error {
    // Pass error to Fiber
    return c.SendFile("file-does-not-exist")
})
```

</TabItem>
</Tabs>

Fiber does not recover from [panics](https://go.dev/blog/defer-panic-and-recover) by default. Add the `Recover` middleware to catch panics in any handler:

```go title="Example"
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/fiber/v3/middleware/recover"
)

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

    app.Use(recover.New())

    app.Get("/", func(c fiber.Ctx) error {
        panic("This panic is caught by fiber")
    })

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

Use `fiber.NewError()` to create an error with a status code. If you omit the message, Fiber uses the standard status text (for example, `404` becomes `Not Found`).

```go title="Example"
app.Get("/", func(c fiber.Ctx) error {
    // 503 Service Unavailable
    return fiber.ErrServiceUnavailable

    // 503 On vacation!
    return fiber.NewError(fiber.StatusServiceUnavailable, "On vacation!")
})
```

## Default Error Handler

Fiber ships with a default error handler that sends **500 Internal Server Error** for generic errors. If the error is a [fiber.Error](https://godoc.org/github.com/gofiber/fiber#Error), the response uses the embedded status code and message.

```go title="Example"
// Default error handler
var DefaultErrorHandler = func(c fiber.Ctx, err error) error {
    // Status code defaults to 500
    code := fiber.StatusInternalServerError
    var e *fiber.Error
    matched := errors.As(err, &e)
    if matched && e != nil {
        code = e.Code
    }
    message := http.StatusText(code)
    if err != nil && !(matched && e == nil) {
        message = err.Error()
    }

    // Set Content-Type: text/plain; charset=utf-8
    c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)

    // Return status code with error message
    return c.Status(code).SendString(message)
}
```

## Custom Error Handler

Set a custom error handler in [`fiber.Config`](../api/fiber.md#errorhandler) when creating a new app.

The default handler covers most cases, but a custom handler lets you react to specific error types—for example, by logging to a service or sending a tailored JSON or HTML response.

The following example shows how to display error pages for different types of errors.

```go title="Example"
// Create a new fiber instance with custom config
app := fiber.New(fiber.Config{
    // Override default error handler
    ErrorHandler: func(ctx fiber.Ctx, err error) error {
        // Status code defaults to 500
        code := fiber.StatusInternalServerError

        // Retrieve the custom status code if it's a *fiber.Error
        var e *fiber.Error
        if errors.As(err, &e) && e != nil {
            code = e.Code
        }

        // Send custom error page
        err = ctx.Status(code).SendFile(fmt.Sprintf("./%d.html", code))
        if err != nil {
            // In case the SendFile fails
            return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
        }

        // Return from handler
        return nil
    },
})

// ...
```

> Special thanks to the [Echo](https://echo.labstack.com/) and [Express](https://expressjs.com/) frameworks for inspiring parts of this error-handling approach.

---

## File: docs/guide/faster-fiber.md

---
id: faster-fiber
title: ⚡ Make Fiber Faster
sidebar_position: 11
---

## Custom JSON Encoder/Decoder

Fiber defaults to the standard `encoding/json` for stability and reliability. If you need more speed, consider these libraries:

- [goccy/go-json](https://github.com/goccy/go-json)
- [bytedance/sonic](https://github.com/bytedance/sonic)
- [segmentio/encoding](https://github.com/segmentio/encoding)
- [minio/simdjson-go](https://github.com/minio/simdjson-go)

```go title="Example"
package main

import "github.com/gofiber/fiber/v3"
import "github.com/goccy/go-json"

func main() {
    app := fiber.New(fiber.Config{
        JSONEncoder: json.Marshal,
        JSONDecoder: json.Unmarshal,
    })

    // ...
}
```

### References

- [Set custom JSON encoder for client](../client/rest.md#setjsonmarshal)
- [Set custom JSON decoder for client](../client/rest.md#setjsonunmarshal)
- [Set custom JSON encoder for application](../api/fiber.md#jsonencoder)
- [Set custom JSON decoder for application](../api/fiber.md#jsondecoder)

## Alternative Regex Engines for `regex()` Constraints

Fiber route patterns still do not support general regex routes, but you can swap
the compiler used by `regex()` parameter constraints through
[`Config.RegexHandler`](../api/fiber.md#regexhandler). This lets you try
high-performance engines such as
[coregex](https://github.com/coregx/coregex) on the matching path.

### Configure `RegexHandler`

Set `RegexHandler` to the compile function you want Fiber to use for `regex()`
constraints.

```go title="Example"
package main

import (
    "github.com/coregx/coregex"
    "github.com/gofiber/fiber/v3"
)

func main() {
    app := fiber.New(fiber.Config{
        RegexHandler: coregex.MustCompile,
    })

    app.Get("/api/:id<regex(\\d+)>", func(c fiber.Ctx) error {
        return c.SendString("ID: " + c.Params("id"))
    })
}
```

You can also set it explicitly to the standard library default:

```go title="Example"
package main

import (
    "regexp"

    "github.com/gofiber/fiber/v3"
)

func main() {
    app := fiber.New(fiber.Config{
        RegexHandler: regexp.MustCompile,
    })

    _ = app
}
```

### Notes

- `RegexHandler` only affects `regex()` parameter constraints
- invalid patterns still panic during route registration because Fiber uses
  `MustCompile`-style semantics
- Fiber may invoke `RegexHandler` more than once per route while parsing raw and
  normalized route patterns during registration
- compiled matchers are reused across requests, so custom matchers must be safe
  for concurrent use

## Related Performance Reading

- [Zero Allocation](../intro.md#zero-allocation): why `Ctx` values are reused across requests and how to copy them safely
- [Benchmarks](../extra/benchmarks.md): how Fiber compares to other frameworks

---

## File: docs/guide/grouping.md

---
id: grouping
title: 🎭 Grouping
sidebar_position: 2
---

:::info
Grouping works like Express.js. Groups are virtual; routes are flattened with the group's prefix and executed in declaration order, mirroring Express.js.
:::

## Paths

Groups can use path prefixes to organize related routes.

```go
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"))
}
```

:::note
Group prefixes follow the same slash-boundary rule as `app.Use`. A prefix must either match the full path or stop at a `/`, so `/api` applies to `/api` and `/api/v1` but not `/apiv1`. Parameter markers (for example `:id`, `:id?`, `*`, and `+`) are processed before checking the boundary.
:::

Groups can also include an optional handler.

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

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

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

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

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

:::caution
Accessing `/api`, `/v1`, or `/v2` directly returns a **404**, so add error handlers as needed.
:::

## Group Handlers

Group handlers can act as routing paths but must call `Next` to continue the flow.

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

    handler := func(c fiber.Ctx) error {
        return c.SendStatus(fiber.StatusOK)
    }
    api := app.Group("/api") // /api

    v1 := api.Group("/v1", func(c fiber.Ctx) error { // middleware for /api/v1
        c.Set("Version", "v1")
        return c.Next()
    })
    v1.Get("/list", handler) // /api/v1/list
    v1.Get("/user", handler) // /api/v1/user

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

## Route

[`Route`](../api/app.md#route) groups routes under a common prefix declared inside a single callback, with an optional name prefix. It is shorthand for nesting with `Group`.

```go
app.Route("/api/v1", func(r fiber.Router) {
    r.Get("/users", handler).Name("users")   // /api/v1/users  (name: v1.users)
    r.Post("/users", handler).Name("create") // /api/v1/users  (name: v1.create)
}, "v1.")
```

## RouteChain

When several HTTP methods share the **same path**, [`RouteChain`](../api/app.md#routechain) lets you declare the path once and chain the verb handlers. An `All` in the chain runs before the verb handlers on that path, acting as route-specific middleware.

```go
app.RouteChain("/events").
    All(func(c fiber.Ctx) error { return c.Next() }). // route-local middleware
    Get(func(c fiber.Ctx) error { return c.SendString("GET /events") }).
    Post(func(c fiber.Ctx) error { return c.SendString("POST /events") })
```

:::note
Within a chain, `All` registers prefix-matched middleware (like [`app.Use`](../api/app.md#use)), not the exact-path `App.All`, so it also runs for sub-paths of the chain path.
:::

---

## File: docs/guide/routing.md

---
id: routing
title: 🔌 Routing
  Routing refers to how an application's endpoints (URIs) respond to client
  requests.
sidebar_position: 1
toc_max_heading_level: 4
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import RoutingHandler from './../partials/routing/handler.md';
import RoutingUse from './../partials/routing/use.md';
import RoutingHandlerTypes from './../partials/routing/handler-types.md';
import RouteAnatomy from '@site/src/components/route-anatomy';
import MiddlewareVisualizer from '@site/src/components/middleware-visualizer';

## Anatomy of a route

A route ties together an HTTP method, a path, and one or more handlers. Hover or click any colored part to jump to the section that explains it:

<RouteAnatomy />

`Get` is the [routing method](#route-handlers), `"/users/:id"` is the [route path](#paths) (the resource, in REST terms) with `:id` a [route parameter](#parameters), and `func(c fiber.Ctx) error` is the [handler](#handler-types) (or [middleware](#middleware)) run when the route matches.

Want to see matching happen? Fire requests at your own route table in the interactive [Route Matcher](../extra/route-matcher.md).

## Route Handlers

<RoutingHandler />

Here is a complete, runnable app for context:

```go title="A minimal Fiber app"
package main

import "github.com/gofiber/fiber/v3"

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

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

    app.Listen(":3000")
}
```

In the shorter examples throughout this guide, `app` is the `*fiber.App` returned by `fiber.New()`, and `handler`/`middleware` stand in for any `func(c fiber.Ctx) error`. Snippets that call `fmt.Println` or `fmt.Fprintf` also need `import "fmt"`.

Beyond the native `func(fiber.Ctx)` forms, Fiber also adapts Express-style, `net/http`, and `fasthttp` handlers. See [Handler types](#handler-types) at the end of this guide for the full list of supported shapes.

## Get vs Use vs All

`Get` (and the other method helpers like `Post` and `Put`) match a **single HTTP method** at an **exact path**. `All` matches an **exact path** across **every** HTTP method. `Use` registers **middleware** that matches by **prefix** and runs in **declaration order**, calling [`c.Next()`](../api/ctx.md#next) to continue the chain.

<Tabs>
<TabItem value="get" label="Get (one method)">

```go
app.Get("/users", func(c fiber.Ctx) error {
    return c.SendString("GET /users")
})

// GET    /users      -> "GET /users"
// POST   /users      -> 405 Method Not Allowed
// GET    /users/42   -> 404 Not Found  (exact match only)
```

</TabItem>
<TabItem value="all" label="All (every method)">

```go
app.All("/ping", func(c fiber.Ctx) error {
    return c.SendString(c.Method() + " /ping")
})

// GET    /ping        -> "GET /ping"
// POST   /ping        -> "POST /ping"
// DELETE /ping        -> "DELETE /ping"
// GET    /ping/extra  -> 404 Not Found  (still exact path)
```

</TabItem>
<TabItem value="use" label="Use (prefix middleware)">

```go
// Empty Use: no path -> matches every request, any method, any path
app.Use(func(c fiber.Ctx) error {
    c.Set("X-Powered-By", "Fiber")
    return c.Next()
})

// Prefixed Use: matches the prefix and anything below a slash boundary
app.Use("/api", func(c fiber.Ctx) error {
    return c.Next()
})

// The empty Use above runs for ALL of these. The notes below show which
// requests ALSO match the prefixed "/api" Use:
// /api        -> also matches "/api" Use   (exact prefix)
// /api/users  -> also matches "/api" Use   (slash boundary)
// /apiv2      -> empty Use only             (no slash boundary)
// /anything   -> empty Use only
```

</TabItem>
<TabItem value="chain" label="Ordered chain">

Multiple handlers that match the same request run in the order you declare them. Each must call `c.Next()` to pass control to the next; if one returns without calling it, the rest of the chain is skipped.

```go
app.Use("/api", func(c fiber.Ctx) error {
    fmt.Println("1: auth check")
    return c.Next()
})

app.Use("/api", func(c fiber.Ctx) error {
    fmt.Println("2: logging")
    return c.Next()
})

app.Get("/api/users", func(c fiber.Ctx) error {
    fmt.Println("3: handler")
    return c.SendString("users")
})

// GET /api/users prints, in order:
//   1: auth check
//   2: logging
//   3: handler
```

</TabItem>
<TabItem value="multi" label="Multiple handlers in one call">

Attach several handlers in a single registration: list the route-specific middleware before the business handler.

```go
app.Get("/users/:id",
    func(c fiber.Ctx) error { // 1: require authentication
        if c.Get("Authorization") == "" {
            return c.SendStatus(fiber.StatusUnauthorized) // returns without c.Next(): stops here
        }
        return c.Next()
    },
    func(c fiber.Ctx) error { // 2: stash data for downstream handlers
        c.Locals("userID", c.Params("id"))
        return c.Next()
    },
    func(c fiber.Ctx) error { // 3: business handler reads the stashed value
        return c.SendString("user " + c.Locals("userID").(string))
    },
)

// GET /users/42 (no Authorization header) -> 401, handlers 2 and 3 never run
// GET /users/42 (with Authorization)      -> "user 42"
```

</TabItem>
</Tabs>

| Helper         | Methods matched | Path matching                              | Typical use                   |
| -------------- | --------------- | ------------------------------------------ | ----------------------------- |
| `Get`/`Post`/… | one             | exact                                      | a specific endpoint           |
| `All`          | every method    | exact                                      | one path, any verb            |
| `Use`          | every method    | prefix (slash boundary); all paths if none given | middleware, mounting sub-apps |

A path that exists only for a different method returns **405 Method Not Allowed**; a path that matches no route at all (including one rejected by a [constraint](#constraints)) returns **404 Not Found**.

## Paths

A route path paired with an HTTP method defines an endpoint. It can be a plain **string** or a **pattern**.

```go
// 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")
})
```

The order in which you declare routes matters: like Express.js, routes are matched in registration order (first match wins), so declare more specific paths before those that contain parameters. Note that method helpers such as `Get` match the exact path only.

:::info
Place routes with variable parameters after fixed paths to avoid unintended matches.
:::

### Path normalization

Before a request is matched, Fiber normalizes its path as [RFC 3986 Section 6.2.2](https://www.rfc-editor.org/rfc/rfc3986#section-6.2.2) describes:

- Percent-encoded unreserved characters (letters, digits, `-`, `.`, `_` and `~`) are decoded, so `/%70rivate` is matched as `/private`. Every other escape stays encoded with uppercase hex digits, so an encoded slash (`%2F`) never splits a segment and `/a%2fb` is matched as `/a%2Fb`. With [`UnescapePath`](../api/fiber.md#config) enabled, every escape is decoded instead.
- `.` and `..` segments are resolved, so `/static/x/../private` and `/static/./private` are both matched as `/static/private`. A `..` never climbs above the root. Empty segments are kept: `/static//private` is a different path from `/static/private`.

Middleware mounted on a prefix therefore sees these spellings of a path under it, and [`c.Path()`](../api/ctx.md#path) returns the normalized path. Decoding happens exactly once: `/%2570rivate` is matched as `/%2570rivate` by default and as `/%70rivate` with `UnescapePath`, and neither becomes `/private`. [`c.OriginalURL()`](../api/ctx.md#originalurl) still returns the request target as the client sent it.

## Parameters

Route parameters are dynamic segments in a path, either named or unnamed, used to capture values from the URL. Retrieve them with the [Params](../api/ctx.md#params) function using the parameter name or, for unnamed parameters, the wildcard (`*`) or plus (`+`) symbol with an index.

The characters `:`, `+`, and `*` introduce parameters. Append `?` to a named segment to make it optional. `+` is a greedy, required wildcard (it must match at least one character); `*` is a greedy, optional wildcard (it can match nothing).

<Tabs>
<TabItem value="named" label="Named, optional, greedy">

```go
// Named 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, required (matches at least one character)
app.Get("/user/+", func(c fiber.Ctx) error {
    return c.SendString(c.Params("+"))
})

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

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

</TabItem>
<TabItem value="literal" label="Literal separators">

The hyphen (`-`), dot (`.`), and colon (`:`) are treated literally between parameters, so you can combine them with route parameters. Fiber's router detects when these characters belong to the literal path.

```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
})
```

</TabItem>
<TabItem value="escaped" label="Escaped characters">

Escape special parameter characters with `\\` to treat them literally. This is useful for custom methods like those in the [Google API Design Guide](https://cloud.google.com/apis/design/custom_methods). Wrap routes in backticks to keep escape sequences clear.

```go
// Matches "/v1/some/resource/name:customVerb" because the colon is escaped
app.Get(`/v1/some/resource/name\:customVerb`, func(c fiber.Ctx) error {
    return c.SendString("Hello, Community")
})

// Matches only the literal path "/*"; an escaped star is not the catch-all route
app.Get(`/\*`, func(c fiber.Ctx) error {
    return c.SendString("literal star")
})
```

</TabItem>
<TabItem value="multi" label="Multiple params per segment">

You can chain multiple named or unnamed parameters, including wildcard and plus segments, within a single segment.

```go
// 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)
```

:::info
Fiber lets multiple parameters share a single path segment, unlike routers such as Express, Gin, and Echo where `:param` always consumes a whole segment. When named parameters are adjacent **with no literal separator between them**, the router cannot know where one parameter ends and the next begins: there is no delimiter in the pattern to split on.

To keep matching deterministic, Fiber assigns every adjacent named parameter except the last a fixed length of **one character**, and the **last** parameter takes the remainder of the segment (up to the next delimiter or end of path). This is why `/:sign:param` against `/@v1` yields `sign=@` and `param=v1`, not `sign=@v` and `param=1`.

If you need a multi-character split, put a literal delimiter between parameters, for example `/:sign-:param` matching `/@v-1`.
:::

</TabItem>
</Tabs>

When a route has several wildcard (`*`) or plus (`+`) segments, retrieve them positionally with a 1-based index matching the symbol: `c.Params("*1")` and `c.Params("*2")` for wildcards, `c.Params("+1")` and `c.Params("+2")` for plus segments. A single wildcard or plus is just `c.Params("*")` or `c.Params("+")`.

Fiber's routing is inspired by Express but intentionally omits regex route patterns due to their performance cost. To validate a parameter against a regular expression, use the [`regex()` constraint](#constraints) described below.

### Constraints

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 introduced 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).

:::caution
Constraints are matching rules, not input validation: if a value fails a constraint, the route simply does not match and Fiber returns **404 Not Found**.
:::

| Constraint        | Example                          | Example matches                                                                             |
| ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------- |
| int               | `:id`                       | 123456789, -123456789                                                                       |
| bool              | `:active`                  | true,false                                                                                  |
| guid              | `:id<guid>`                      | CD2C1638-1638-72D5-1638-DEADBEEF1638                                                        |
| float             | `:weight<float>`                 | 1.234, -1001.01e8, 3.14                                                                     |
| minLen(value)     | `:username<minLen(4)>`           | Test (must be at least 4 characters)                                                        |
| maxLen(value)     | `:filename<maxLen(8)>`           | MyFile (must be no more than 8 characters)                                                  |
| len(length)       | `:filename<len(12)>`             | somefile.txt (exactly 12 characters)                                                        |
| min(value)        | `:age<min(18)>`                  | 19 (Integer value must be at least 18)                                                      |
| max(value)        | `:age<max(120)>`                 | 91 (Integer value must be no more than 120)                                                 |
| range(min,max)    | `:age<range(18,120)>`            | 91 (Integer value must be at least 18 but no more than 120)                                 |
| alpha             | `:name<alpha>`                   | Rick (String must consist of one or more alphabetical characters, a-z and case-insensitive) |
| datetime          | `:dob<datetime(2006\\-01\\-02)>` | 2005-11-01                                                                                  |
| regex(expression) | `:date<regex(\d{4}-\d{2}-\d{2})>` | 2022-08-27 (Must match regular expression)                                                  |

Constraint names and arguments are always taken from the pattern as written, even with the default case-insensitive routing: `:code<regex([A-Z]{2})>` keeps matching uppercase codes only, a `datetime` layout keeps its `T` and `Z`, and a custom constraint registered under a mixed-case name is found.

#### Examples

<Tabs>
<TabItem value="single-constraint" label="Single Constraint">

```go
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
// Not Found
```

</TabItem>
<TabItem value="multiple-constraints" label="Multiple Constraints">

You can use `;` for multiple constraints.

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

// curl -X GET http://localhost:3000/120000
// Not Found

// curl -X GET http://localhost:3000/1
// Not Found

// curl -X GET http://localhost:3000/250
// 250
```

</TabItem>
<TabItem value="regex-constraint" label="Regex Constraint">

Fiber precompiles the regex when registering routes, so the pattern is matched (not recompiled) on each request.

```go
app.Get(`/:date<regex(\d{4}-\d{2}-\d{2})>`, func(c fiber.Ctx) error {
    return c.SendString(c.Params("date"))
})

// curl -X GET http://localhost:3000/125
// Not Found

// curl -X GET http://localhost:3000/test
// Not Found

// curl -X GET http://localhost:3000/2022-08-27
// 2022-08-27
```

</TabItem>
</Tabs>

:::caution
When using the datetime constraint, prefix routing characters (`*`, `+`, `?`, `:`, `/`, `<`, `>`, `;`, `(`, `)`) with `\\` to avoid misparsing.
:::

#### Optional Parameter Example

You can impose constraints on optional parameters as well.

```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
// Not Found
```

#### Custom Constraint

Custom constraints can be added to Fiber using the `app.RegisterCustomConstraint` method. Your constraints have to be compatible with the `CustomConstraint` interface.

:::caution
Attention, custom constraints can now override built-in constraints. If a custom constraint has the same name as a built-in constraint, the custom constraint will be used instead. This allows for more flexibility in defining route parameter constraints.
:::

Add external constraints when you need stricter rules, such as verifying that a parameter is a valid ULID.

```go
// CustomConstraint is an interface for custom constraints
type CustomConstraint interface {
    // Name returns the name of the constraint.
    // This name is used in the constraint matching.
    Name() string

    // Execute executes the constraint.
    // It returns true if the constraint is matched and right.
    // param is the parameter value to check.
    // args are the constraint arguments.
    Execute(param string, args ...string) bool
}
```

You can check the example below:

```go
type UlidConstraint struct {
    fiber.CustomConstraint
}

func (*UlidConstraint) Name() string {
    return "ulid"
}

func (*UlidConstraint) Execute(param string, args ...string) bool {
    _, err := ulid.Parse(param)
    return err == nil
}

func main() {
    app := fiber.New()
    app.RegisterCustomConstraint(&UlidConstraint{})

    app.Get("/login/:id", func(c fiber.Ctx) error {
        return c.SendString("...")
    })

    app.Listen(":3000")

    // /login/01HK7H9ZE5BFMK348CPYP14S0Z -> 200
    // /login/12345 -> 404
}
```

#### ConstraintHandler Interface

In addition to the `CustomConstraint` interface, Fiber v3 provides a more powerful `ConstraintHandler` interface that supports precomputation at route registration time. All built-in constraints implement this interface.

```go
// ConstraintHandler is the interface that all constraints must implement.
type ConstraintHandler interface {
    // Name returns the constraint identifier used in route patterns.
    Name() string

    // Execute validates a request parameter value against the constraint.
    // data contains the pre-typed constraint data produced by Analyze().
    Execute(param string, data []any) bool
}
```

Optionally, a constraint can implement `ConstraintAnalyzer` to preprocess data at registration time, avoiding repeated parsing on every request:

```go
// ConstraintAnalyzer is an optional interface for registration-time precomputation.
type ConstraintAnalyzer interface {
    // Analyze preprocesses constraint data at route registration time.
    // Returns pre-typed values that will be stored in Constraint.Data.
    Analyze(args []string) ([]any, error)
}
```

:::note
Existing `CustomConstraint` implementations continue to work unchanged. They are automatically wrapped to satisfy `ConstraintHandler`. Custom constraints that also implement `ConstraintAnalyzer` will have their `Analyze` method called at registration time.
:::

:::tip Try it live
Test route patterns, registration order, and constraints against real requests in the interactive [Route Matcher](../extra/route-matcher.md) tool.
:::

## Middleware

Functions that are designed to make changes to the request or response are called **middleware functions**. [`c.Next()`](../api/ctx.md#next) passes control to the next handler in the matched chain (middleware or route handler); if a handler returns without calling it, the remaining handlers are skipped.

```go title="Example of a middleware function"
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!")
})
```

Once a route matches, its handlers run as one chain in registration order; each handler decides with `c.Next()` whether the rest of the chain runs. Step through the chain yourself, including what happens when a middleware short-circuits instead of calling `c.Next()`:

<MiddlewareVisualizer />

See [Get vs Use vs All](#get-vs-use-vs-all) for how `Use` prefix matching differs from exact route matching, and how multiple handlers run in order.

### Use

<RoutingUse />

### Adding or removing routes at runtime

:::caution
Defining all routes before the app starts is strongly recommended. You can still change them at runtime with [`RebuildTree`](../api/app.md#rebuildtree), [`RemoveRoute`](../api/app.md#removeroute), [`RemoveRouteByName`](../api/app.md#removeroutebyname), and [`RemoveRouteFunc`](../api/app.md#removeroutefunc), but these operations are not thread-safe and are performance-intensive, so use them sparingly and only in development.
:::

## Grouping

If you have many endpoints, you can organize your routes using `Group`.

```go
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"))
}
```

More information about this in our [Grouping Guide](./grouping.md).

### Route

[`Route`](../api/app.md#route) is shorthand for [`Group`](#grouping): it scopes a set of routes under a common prefix declared inside a single callback, with an optional name prefix.

```go
app.Route("/api/v1", func(r fiber.Router) {
    r.Get("/users", handler).Name("users")   // /api/v1/users  (name: v1.users)
    r.Post("/users", handler).Name("create") // /api/v1/users  (name: v1.create)
}, "v1.")
```

### RouteChain

When several HTTP methods share the **same path**, [`RouteChain`](../api/app.md#routechain) lets you declare the path once and chain the verb handlers. An `All` in the chain runs before the verb handlers on that path, acting as route-specific middleware.

```go
app.RouteChain("/events").
    All(func(c fiber.Ctx) error { return c.Next() }). // route-local middleware
    Get(func(c fiber.Ctx) error { return c.SendString("GET /events") }).
    Post(func(c fiber.Ctx) error { return c.SendString("POST /events") })
```

:::note
Within a chain, `All` registers prefix-matched middleware (like [`Use`](#use)), not the exact-path `App.All`, so it also runs for sub-paths of the chain path.
:::

Pick the helper that fits: a single endpoint uses `Get`/`Post`/…; a fixed set of methods on one path uses [`Add`](#route-handlers); one path with many methods (fluently) uses `RouteChain`; many paths under a shared prefix use [`Group`](#grouping) or `Route`.

## Automatic HEAD routes

Fiber automatically registers a `HEAD` route for every `GET` route you add. The generated handler chain mirrors the `GET` chain, so `HEAD` requests reuse middleware, status codes, and headers while the response body is suppressed. This covers the routes of mounted sub-apps at any nesting depth, and routes added at runtime get their `HEAD` companion when [`RebuildTree`](../api/app.md#rebuildtree) publishes them.

```go title="GET handlers automatically expose HEAD"
app := fiber.New()

app.Get("/users/:id", func(c fiber.Ctx) error {
    c.Set("X-User", c.Params("id"))
    return c.SendStatus(fiber.StatusOK)
})

// HEAD /users/:id now returns the same headers and status without a body.
```

You can still register dedicated `HEAD` handlers, even with auto-registration enabled, and Fiber replaces the generated route so your implementation wins:

```go title="Override the generated HEAD handler"
app.Head("/users/:id", func(c fiber.Ctx) error {
    return c.SendStatus(fiber.StatusNoContent)
})
```

To opt out globally, start the app with `DisableHeadAutoRegister`:

```go title="Disable automatic HEAD registration"
handler := func(c fiber.Ctx) error {
    c.Set("X-User", c.Params("id"))
    return c.SendStatus(fiber.StatusOK)
}

app := fiber.New(fiber.Config{DisableHeadAutoRegister: true})
app.Get("/users/:id", handler) // HEAD /users/:id now returns 405 unless you add it manually.
```

Auto-generated `HEAD` routes participate in every router scope, including `Group` hierarchies, mounted sub-apps, parameterized and wildcard paths, and static file helpers. They also appear in route listings such as `app.Stack()` so tooling sees both the `GET` and `HEAD` entries.

## Handler types

<RoutingHandlerTypes />

---

## File: docs/guide/utils.md

---
id: utils
title: 🧰 Utils
sidebar_position: 9
toc_max_heading_level: 4
---

## Generics

### Convert

Converts a string to a specific type while handling errors and optional defaults.
It wraps conversion and fallback logic to keep your code clean and consistent.

```go title="Signature"
func Convert[T any](value string, converter func(string) (T, error), defaultValue ...T) (T, error)
```

```go title="Example"
// GET http://example.com/id/bb70ab33-d455-4a03-8d78-d3c1dacae9ff
app.Get("/id/:id", func(c fiber.Ctx) error {
    fiber.Convert(c.Params("id"), uuid.Parse)                   // UUID(bb70ab33-d455-4a03-8d78-d3c1dacae9ff), nil
})

// GET http://example.com/search?id=65f6f54221fb90e6a6b76db7
app.Get("/search", func(c fiber.Ctx) error {
    fiber.Convert(c.Query("id"), mongo.ParseObjectID)           // objectid(65f6f54221fb90e6a6b76db7), nil
    fiber.Convert(c.Query("id"), uuid.Parse)                    // uuid.Nil, error(cannot parse given uuid)
    fiber.Convert(c.Query("id"), uuid.Parse, mongo.NewObjectID) // new object id generated and return nil as error.
    return nil
})

// ...
```

### GetReqHeader

Retrieves an HTTP request header as a specific type using generics.

```go title="Signature"
func GetReqHeader[V GenericType](c Ctx, key string, defaultValue ...V) V
```

```go title="Example"
app.Get("/search", func(c fiber.Ctx) error {
    // curl -X GET http://example.com/search -H "X-Request-ID: 12345" -H "X-Request-Name: John"
    fiber.GetReqHeader[int](c, "X-Request-ID")               // => returns 12345 as integer.
    fiber.GetReqHeader[string](c, "X-Request-Name")          // => returns "John" as string.
    fiber.GetReqHeader[string](c, "unknownParam", "default") // => returns "default" as string.
    // ...
})
```

### Locals

Reads or writes local values in the request context using generics.

```go title="Signature"
// Set a value
func Locals[V any](c Ctx, key any, value ...V) V
// Get a value
func Locals[V any](c Ctx, key any) V
```

```go title="Example"
app.Use("/user/:user/:id", func(c fiber.Ctx) error {
    // set local values
    fiber.Locals[string](c, "user", "john")
    fiber.Locals[int](c, "id", 25)
    // ...
    
    return c.Next()
})


app.Get("/user/*", func(c fiber.Ctx) error {
    // get local values
    name := fiber.Locals[string](c, "user") // john
    age := fiber.Locals[int](c, "id")       // 25
    // ...
})
```

### Params

Retrieves route parameters as a specific type.

```go title="Signature"
func Params[V GenericType](c Ctx, key string, defaultValue ...V) V
```

```go title="Example"
app.Get("/user/:user/:id", func(c fiber.Ctx) error {
    // http://example.com/user/john/25
    fiber.Params[int](c, "id")               // => returns 25 as integer.
    fiber.Params[int](c, "unknownParam", 99) // => returns the default 99 as integer.
    // ...
    return c.SendString("Hello, " + fiber.Params[string](c, "user"))
})
```

### Query

Retrieves query parameters as a specific type.

```go title="Signature"
func Query[V GenericType](c Ctx, key string, defaultValue ...V) V
```

```go title="Example"
app.Get("/search", func(c fiber.Ctx) error {
    // http://example.com/search?name=john&age=25
    fiber.Query[string](c, "name")                    // => returns "john"
    fiber.Query[int](c, "age")                        // => returns 25 as integer.
    fiber.Query[string](c, "unknownParam", "default") // => returns "default" as string.
    // ...
})
```

### RoutePatternMatch

Checks whether a given path matches a Fiber route pattern. Useful for testing
patterns without registering them. Patterns may contain parameters, wildcards
and optional segments. An optional `Config` allows control over case sensitivity
and strict routing.

The path is normalized exactly the way the router normalizes an incoming
request before matching, so the answer agrees with what the app would actually
do. In particular, with the default `StrictRouting: false` a trailing slash on
the path is ignored, so `RoutePatternMatch("/a/", "/a")` reports `true`. Set
`StrictRouting: true` if you need the two forms to be distinguished.

```go title="Signature"
func RoutePatternMatch(path, pattern string, cfg ...Config) bool
```

```go title="Example"
fiber.RoutePatternMatch("/user/john", "/user/:name") // true

fiber.RoutePatternMatch(
    "/User/john",
    "/user/:name",
    fiber.Config{CaseSensitive: true},
) // false
```

## 2. Official Technical Reference & Guides (gofiber/docs)

## File: README.md

# Website

This website is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator.

## Prerequisites

- Node.js `>= 20`
- npm `>= 10`

## Installation

```
$ npm ci
```

### Local Development

```
$ npm run start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

## Build

```
$ npm run build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

Build only docs site:

```
$ npm run build:docs
```

Build only homepage:

```
$ npm run build:home
```

Run setup checks (TypeScript + both build targets):

```
$ npm run check
```

## Deployment

Using SSH:

```
$ USE_SSH=true npm run deploy
```

Not using SSH:

```
$ GIT_USER=<Your GitHub username> npm run deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/paseto/README.md

---
id: paseto
---

# Paseto


[](https://gofiber.io/discord)


PASETO returns a Web Token (PASETO) auth middleware.

- For valid token, it sets the payload data in Ctx.Locals and calls next handler.
- For invalid token, it returns "401 - Unauthorized" error.
- For missing token, it returns "400 - BadRequest" error.

**Note: Requires Go 1.18 and above**

## Install

This middleware supports Fiber v2.

```
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/paseto
go get -u github.com/o1egl/paseto
```

## Signature

```go
pasetoware.New(config ...pasetoware.Config) func(*fiber.Ctx) error
```

## Config

| Property       | Type                            | Description                                                                                                                                                                                             | Default                         |
|:---------------|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------|
| Next           | `func(*Ctx) bool`               | Defines a function to skip middleware                                                                                                                                                                   | `nil`                           |
| SuccessHandler | `func(*fiber.Ctx) error`        | SuccessHandler defines a function which is executed for a valid token.                                                                                                                                  | `c.Next()`                      |
| ErrorHandler   | `func(*fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token.                                                                                                                                 | `401 Invalid or expired PASETO` |
| Validate       | `PayloadValidator`              | Defines a function to validate if payload is valid. Optional. In case payload used is created using `CreateToken` function. If token is created using another function, this function must be provided. | `nil`                           |
| SymmetricKey   | `[]byte`                        | Secret key to encrypt token. If present the middleware will generate local tokens.                                                                                                                      | `nil`                           |
| PrivateKey     | `ed25519.PrivateKey`            | Secret key to sign the tokens. If present (along with its `PublicKey`) the middleware will generate public tokens.                                                                                      | `nil`                           
| PublicKey      | `crypto.PublicKey`              | Public key to verify the tokens. If present (along with `PrivateKey`) the middleware will generate public tokens.                                                                                       | `nil`                           
| ContextKey     | `string`                        | Context key to store user information from the token into context.                                                                                                                                      | `"auth-token"`                  |
| TokenLookup    | `[2]string`                     | TokenLookup is a string slice with size 2, that is used to extract token from the request                                                                                                               | `["header","Authorization"]`    |

## Instructions

When using this middleware, and creating a token for authentication, you can use the function pasetoware.CreateToken,
that will create a token, encrypt or sign it and returns the PASETO token.

Passing a `SymmetricKey` in the Config results in a local (encrypted) token, while passing a `PublicKey`
and `PrivateKey` results in a public (signed) token.

In case you want to use your own data structure, is needed to provide the `Validate` function in `paseware.Config`, that
will return the data stored in the token, and a error.

## Examples

Below have a list of some examples that can help you start to use this middleware. In case of any additional example
that doesn't show here, please take a look at the test file.

### SymmetricKey

```go
package main

import (
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/o1egl/paseto"

	pasetoware "github.com/gofiber/contrib/paseto"
)

const secretSymmetricKey = "symmetric-secret-key (size = 32)"

func main() {

	app := fiber.New()

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// Paseto Middleware with local (encrypted) token
	apiGroup := app.Group("api", pasetoware.New(pasetoware.Config{
		SymmetricKey: []byte(secretSymmetricKey),
		TokenPrefix:  "Bearer",
	}))

	// Restricted Routes
	apiGroup.Get("/restricted", restricted)

	err := app.Listen(":8088")
	if err != nil {
		return
	}
}

func login(c *fiber.Ctx) error {
	user := c.FormValue("user")
	pass := c.FormValue("pass")

	// Throws Unauthorized error
	if user != "john" || pass != "doe" {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	// Create token and encrypt it
	encryptedToken, err := pasetoware.CreateToken([]byte(secretSymmetricKey), user, 12*time.Hour, pasetoware.PurposeLocal)
	if err != nil {
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return c.JSON(fiber.Map{"token": encryptedToken})
}

func accessible(c *fiber.Ctx) error {
	return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
	payload := c.Locals(pasetoware.DefaultContextKey).(string)
	return c.SendString("Welcome " + payload)
}

```

#### Test it

_Login using username and password to retrieve a token._

```
curl --data "user=john&pass=doe" http://localhost:8088/login
```

_Response_

```json
{
  "token": "v2.local.eY7o9YAJ7Uqyo0JdyfHXKVARj3HgBhqIHckPgNIJOU6u489CXYL6bpOXbEtTB_nNM7nTFpcRVi7YAtJToxbxkkraHmE39pqjnBgkca-URgE-jhZGuhGu7ablmK-8tVoe5iY8mQqWFuJHAznTASUHh4AG55AMUcIALi6pEG28lAgVfw2azvnvbg4JOVZnjutcOVswd-ErsAuGtuEZkTmX7BfaLaO9ZvEX9cHahYPajuRjwU2TQrcpqITg-eYMNA1NuO8OVdnGf0mkUk6ElJUTZqhx4CSSylNXr7IlOwzTbUotEDAQTcNP7IRZI3VfpnRgnmtnZ5s.bnVsbAY"
}
```

_Request a restricted resource using the token in Authorization request header._

```
curl localhost:8088/api/restricted -H "Authorization: Bearer v2.local.eY7o9YAJ7Uqyo0JdyfHXKVARj3HgBhqIHckPgNIJOU6u489CXYL6bpOXbEtTB_nNM7nTFpcRVi7YAtJToxbxkkraHmE39pqjnBgkca-URgE-jhZGuhGu7ablmK-8tVoe5iY8mQqWFuJHAznTASUHh4AG55AMUcIALi6pEG28lAgVfw2azvnvbg4JOVZnjutcOVswd-ErsAuGtuEZkTmX7BfaLaO9ZvEX9cHahYPajuRjwU2TQrcpqITg-eYMNA1NuO8OVdnGf0mkUk6ElJUTZqhx4CSSylNXr7IlOwzTbUotEDAQTcNP7IRZI3VfpnRgnmtnZ5s.bnVsbA"
```

_Response_

```
Welcome john
```

### SymmetricKey + Custom Validator callback

```go
package main

import (
	"encoding/json"
	"time"

	"github.com/o1egl/paseto"

	pasetoware "github.com/gofiber/contrib/paseto"
)

const secretSymmetricKey = "symmetric-secret-key (size = 32)"

type customPayloadStruct struct {
	Name      string    `json:"name"`
	ExpiresAt time.Time `json:"expiresAt"`
}

func main() {

	app := fiber.New()

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// Paseto Middleware with local (encrypted) token
	apiGroup := app.Group("api", pasetoware.New(pasetoware.Config{
		SymmetricKey: []byte(secretSymmetricKey),
		TokenPrefix:  "Bearer",
		Validate: func(decrypted []byte) (any, error) {
			var payload customPayloadStruct
			err := json.Unmarshal(decrypted, &payload)
			return payload, err
		},
	}))

	// Restricted Routes
	apiGroup.Get("/restricted", restricted)

	err := app.Listen(":8088")
	if err != nil {
		return
	}
}

func login(c *fiber.Ctx) error {
	user := c.FormValue("user")
	pass := c.FormValue("pass")

	// Throws Unauthorized error
	if user != "john" || pass != "doe" {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	// Create the payload
	payload := customPayloadStruct{
		Name:      "John Doe",
		ExpiresAt: time.Now().Add(12 * time.Hour),
	}

	// Create token and encrypt it
	encryptedToken, err := paseto.NewV2().Encrypt([]byte(secretSymmetricKey), payload, nil)
	if err != nil {
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return c.JSON(fiber.Map{"token": encryptedToken})
}

func accessible(c *fiber.Ctx) error {
	return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
	payload := c.Locals(pasetoware.DefaultContextKey).(customPayloadStruct)
	return c.SendString("Welcome " + payload.Name)
}

```

#### Test it

_Login using username and password to retrieve a token._

```
curl --data "user=john&pass=doe" http://localhost:8088/login
```

_Response_

```json
{
  "token": "v2.local.OSnDEMUndq8JpRdCD8yX-mr-Z0-Mi85Jw0ftxseiNLCbRc44Mxl5dnn-SV9Qew1n9Y44wXZwm_FG279cILJk7lYc_B_IoMCRBudJE7qMgctkD9UBM-ZRZgCX9ekJh3S1Oo6Erp7bO-omPra5.bnVsbA"
}
```

_Request a restricted resource using the token in Authorization request header._

```
curl localhost:8088/api/restricted -H "Authorization: Bearer v2.local.OSnDEMUndq8JpRdCD8yX-mr-Z0-Mi85Jw0ftxseiNLCbRc44Mxl5dnn-SV9Qew1n9Y44wXZwm_FG279cILJk7lYc_B_IoMCRBudJE7qMgctkD9UBM-ZRZgCX9ekJh3S1Oo6Erp7bO-omPra5.bnVsbA"
```

_Response_

```
Welcome John Doe
```

### PublicPrivate Key

```go
package main

import (
	"crypto/ed25519"
	"encoding/hex"
	"time"

	"github.com/gofiber/fiber/v2"

	pasetoware "github.com/gofiber/contrib/paseto"
)

const privateKeySeed = "e9c67fe2433aa4110caf029eba70df2c822cad226b6300ead3dcae443ac3810f"

var seed, _ = hex.DecodeString(privateKeySeed)
var privateKey = ed25519.NewKeyFromSeed(seed)

type customPayloadStruct struct {
	Name      string    `json:"name"`
	ExpiresAt time.Time `json:"expiresAt"`
}

func main() {

	app := fiber.New()

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// Paseto Middleware with local (encrypted) token
	apiGroup := app.Group("api", pasetoware.New(pasetoware.Config{
		TokenPrefix: "Bearer",
		PrivateKey:  privateKey,
		PublicKey:   privateKey.Public(),
	}))

	// Restricted Routes
	apiGroup.Get("/restricted", restricted)

	err := app.Listen(":8088")
	if err != nil {
		return
	}
}

func login(c *fiber.Ctx) error {
	user := c.FormValue("user")
	pass := c.FormValue("pass")

	// Throws Unauthorized error
	if user != "john" || pass != "doe" {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	// Create token and encrypt it
	encryptedToken, err := pasetoware.CreateToken(privateKey, user, 12*time.Hour, pasetoware.PurposePublic)
	if err != nil {
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return c.JSON(fiber.Map{"token": encryptedToken})
}

func accessible(c *fiber.Ctx) error {
	return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
	payload := c.Locals(pasetoware.DefaultContextKey).(string)
	return c.SendString("Welcome " + payload)
}

```

#### Test it

_Login using username and password to retrieve a token._

```
curl --data "user=john&pass=doe" http://localhost:8088/login
```

_Response_

```json
{
  "token": "v2.public.eyJhdWQiOiJnb2ZpYmVyLmdvcGhlcnMiLCJkYXRhIjoiam9obiIsImV4cCI6IjIwMjMtMDctMTNUMDg6NDk6MzctMDM6MDAiLCJpYXQiOiIyMDIzLTA3LTEyVDIwOjQ5OjM3LTAzOjAwIiwianRpIjoiMjIzYjM0MjQtNWNkZS00NDFhLWJiZWEtZjBjYWFhYTdiYWFlIiwibmJmIjoiMjAyMy0wNy0xMlQyMDo0OTozNy0wMzowMCIsInN1YiI6InVzZXItdG9rZW4ifWiqK_yg0eJbIs2hnup4NuBYg7v4lxh33zEhEljsH7QUaZXAdtbCPK7cN-NSfSxrw68owwgo-dOlPrD7lc5M_AU.bnVsbA"
}
```

_Request a restricted resource using the token in Authorization request header._

```
curl localhost:8088/api/restricted -H "Authorization: Bearer v2.public.eyJhdWQiOiJnb2ZpYmVyLmdvcGhlcnMiLCJkYXRhIjoiam9obiIsImV4cCI6IjIwMjMtMDctMTNUMDg6NDk6MzctMDM6MDAiLCJpYXQiOiIyMDIzLTA3LTEyVDIwOjQ5OjM3LTAzOjAwIiwianRpIjoiMjIzYjM0MjQtNWNkZS00NDFhLWJiZWEtZjBjYWFhYTdiYWFlIiwibmJmIjoiMjAyMy0wNy0xMlQyMDo0OTozNy0wMzowMCIsInN1YiI6InVzZXItdG9rZW4ifWiqK_yg0eJbIs2hnup4NuBYg7v4lxh33zEhEljsH7QUaZXAdtbCPK7cN-NSfSxrw68owwgo-dOlPrD7lc5M_AU.bnVsbA"
```

_Response_

```
Welcome John Doe
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/otelfiber/example/README.md

---
id: otelfiber-example
---

# Example

An HTTP server using gofiber fiber and instrumentation. The server has a
`/users/:id` endpoint. The server generates span information to
`stdout`.

These instructions expect you have
[docker-compose](https://docs.docker.com/compose/) installed.

Bring up the `fiber-server` and `fiber-client` services to run the
example:

```sh
docker-compose up --detach fiber-server fiber-client
```

The `fiber-client` service sends just one HTTP request to `fiber-server`
and then exits. View the span generated by `fiber-server` in the logs:

```sh
docker-compose logs fiber-server
```

Shut down the services when you are finished with the example:

```sh
docker-compose down
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/otelfiber/README.md

---
id: otelfiber
---

# Otelfiber


[](https://gofiber.io/discord)


[OpenTelemetry](https://opentelemetry.io/) support for Fiber.

Can be found on [OpenTelemetry Registry](https://opentelemetry.io/registry/instrumentation-go-fiber/).

**Note: Requires Go 1.19 and above**

## Install

This middleware supports Fiber v2.

```
go get -u github.com/gofiber/contrib/otelfiber/v2
```

## Signature

```go
otelfiber.Middleware(opts ...otelfiber.Option) fiber.Handler
```

## Config
You can configure the middleware using functional parameters


| Function                | Argument Type                            | Description                                                                      | Default                                                             |
| :------------------------ | :-------------------------------- | :--------------------------------------------------------------------------------- | :-------------------------------------------------------------------- |
| `WithNext`                    | `func(*fiber.Ctx) bool`         | Define a function to skip this middleware when returned true .| nil                                                                 |
| `WithTracerProvider`          | `oteltrace.TracerProvider`      | Specifies a tracer provider to use for creating a tracer.                         | nil - the global tracer provider is used                                   |
| `WithMeterProvider`           | `otelmetric.MeterProvider`      | Specifies a meter provider to use for reporting.                                     | nil - the global meter provider is used                                                             |
| `WithPort`                    | `int`                          | Specifies the value to use when setting the `net.host.port` attribute on metrics/spans.                            | Defaults to (`80` for `http`, `443` for `https`)              |
| `WithPropagators`             | `propagation.TextMapPropagator` | Specifies propagators to use for extracting information from the HTTP requests.                     | If none are specified, global ones will be used                                                               |
| `WithServerName`              | `string`                       | Specifies the value to use when setting the `http.server_name` attribute on metrics/spans.                                          | -                                                                   |
| `WithSpanNameFormatter`       | `func(*fiber.Ctx) string`       | Takes a function that will be called on every request and the returned string will become the span Name.                                   | Default formatter returns the route pathRaw |
| `WithCustomAttributes`        | `func(*fiber.Ctx) []attribute.KeyValue` | Define a function to add custom attributes to the span.                  | nil                                                                 |
| `WithCustomMetricAttributes`  | `func(*fiber.Ctx) []attribute.KeyValue` | Define a function to add custom attributes to the metrics.               | nil                                                                 |
| `WithCollectClientIP`         | `bool` | Specifies whether to collect the client's IP address from the request. | true |

## Usage

Please refer to [example](./example)

## Example

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/opafiber/README.md

---
id: opafiber
---

# Opafiber


[](https://gofiber.io/discord)


[Open Policy Agent](https://github.com/open-policy-agent/opa) support for Fiber.

**Note: Requires Go 1.19 and above**

## Install

```
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/opafiber/v2
```

## Signature

```go
opafiber.New(config opafiber.Config) fiber.Handler

```

## Config

| Property              | Type                | Description                                                  | Default                                                             |
|:----------------------|:--------------------|:-------------------------------------------------------------|:--------------------------------------------------------------------|
| RegoQuery             | `string`            | Required - Rego query                                        | -                                                                   |
| RegoPolicy            | `io.Reader`         | Required - Rego policy                                       | -                                                                   |
| IncludeQueryString    | `bool`              | Include query string as input to rego policy                 | `false`                                                             |
| DeniedStatusCode      | `int`               | Http status code to return when policy denies request        | `400`                                                               |
| DeniedResponseMessage | `string`            | Http response body text to return when policy denies request | `""`                                                                |
| IncludeHeaders        | `[]string`          | Include headers as input to rego policy                      | -                                                                   |
| InputCreationMethod   | `InputCreationFunc` | Use your own function to provide input for OPA               | `func defaultInput(ctx *fiber.Ctx) (map[string]interface{}, error)` |

## Types

```go
type InputCreationFunc func(c *fiber.Ctx) (map[string]interface{}, error)
```

## Usage

OPA Fiber middleware sends the following example data to the policy engine as input:

```json
{
  "method": "GET",
  "path": "/somePath",
  "query": {
    "name": ["John Doe"]
  },
  "headers": {
    "Accept": "application/json",
    "Content-Type": "application/json"
  }
}
```

```go
package main

import (
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/contrib/opafiber/v2"
)

func main() {
	app := fiber.New()
	module := `
package example.authz

default allow := false

allow {
	input.method == "GET"
}
`

	cfg := opafiber.Config{
		RegoQuery:             "data.example.authz.allow",
		RegoPolicy:            bytes.NewBufferString(module),
		IncludeQueryString:    true,
		DeniedStatusCode:      fiber.StatusForbidden,
		DeniedResponseMessage: "status forbidden",
		IncludeHeaders:        []string{"Authorization"},
		InputCreationMethod:   func (ctx *fiber.Ctx) (map[string]interface{}, error) {
            return map[string]interface{}{
                "method": ctx.Method(),
                "path": ctx.Path(),
            }, nil
        },
	}
	app.Use(opafiber.New(cfg))

	app.Get("/", func(ctx *fiber.Ctx) error {
		return ctx.SendStatus(200)
	})

	app.Listen(":8080")
}
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/monitor/README.md

---
id: monitor
---

# Monitor





Monitor middleware for [Fiber](https://github.com/gofiber/fiber) that reports server metrics, inspired by [express-status-monitor](https://github.com/RafalWilinski/express-status-monitor)



## Install

This middleware supports Fiber v3.

```
go get -u github.com/gofiber/fiber/v3
go get -u github.com/gofiber/contrib/monitor
```

### Signature

```go
monitor.New(config ...monitor.Config) fiber.Handler
```

### Config

| Property   | Type                      | Description                                                                          | Default                                                                     |
| :--------- | :------------------------ | :----------------------------------------------------------------------------------- | :-------------------------------------------------------------------------- |
| Title      | `string`                  | Metrics page title.                                                                  | `Fiber Monitor`                                                             |
| Refresh    | `time.Duration`           | Refresh period.                                                                      | `3 seconds`                                                                 |
| APIOnly    | `bool`                    | Whether the service should expose only the montioring API.                           | `false`                                                                     |
| Next       | `func(c *fiber.Ctx) bool` | Define a function to add custom fields.                                              | `nil`                                                                       |
| CustomHead | `string`                  | Custom HTML code to Head Section(Before End).                                        | `empty`                                                                     |
| FontURL    | `string`                  | FontURL for specilt font resource path or URL. also you can use relative path.       | `https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap` |
| ChartJsURL | `string`                  | ChartJsURL for specilt chartjs library, path or URL, also you can use relative path. | `https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js`        |

### Example

```go
package main

import (
    "log"

    "github.com/gofiber/fiber/v3"
    "github.com/gofiber/contrib/monitor"
)

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

    // Initialize default config (Assign the middleware to /metrics)
    app.Get("/metrics", monitor.New())

    // Or extend your config for customization
    // Assign the middleware to /metrics
    // and change the Title to `MyService Metrics Page`
    app.Get("/metrics", monitor.New(monitor.Config{Title: "MyService Metrics Page"}))

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


## Default Config

```go
var ConfigDefault = Config{
	Title:      defaultTitle,
	Refresh:    defaultRefresh,
	FontURL:    defaultFontURL,
	ChartJsURL: defaultChartJSURL,
	CustomHead: defaultCustomHead,
	APIOnly:    false,
	Next:       nil,
}
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/loadshed/README.md

---
id: loadshed
---

# LoadShed


[](https://gofiber.io/discord)


The LoadShed middleware for [Fiber](https://github.com/gofiber/fiber) is designed to help manage server load by shedding requests based on certain load criteria.

**Note: Requires Go 1.19 and above**

## Install

This middleware supports Fiber v2

```
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/loadshed
```

## Signatures

```go
loadshed.New(config ...loadshed.Config) fiber.Handler
```

## Examples

To use the LoadShed middleware in your Fiber application, import it and apply it to your Fiber app. Here's an example:

```go
package main

import (
  "github.com/gofiber/fiber/v2"
  loadshed "github.com/gofiber/contrib/loadshed"
)

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

  // Configure and use LoadShed middleware
  app.Use(loadshed.New(loadshed.Config{
    Criteria: &loadshed.CPULoadCriteria{
      LowerThreshold: 0.75, // Set your own lower threshold
      UpperThreshold: 0.90, // Set your own upper threshold
      Interval:       10 * time.Second,
      Getter:         &loadshed.DefaultCPUPercentGetter{},
    },
  }))

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

  app.Listen(":3000")
}
```

## Config

The LoadShed middleware in Fiber offers various configuration options to tailor the load shedding behavior according to the needs of your application.

| Property | Type                    | Description                                          | Default                 |
| :------- | :---------------------- | :--------------------------------------------------- | :---------------------- |
| Next     | `func(*fiber.Ctx) bool` | Function to skip this middleware when returned true. | `nil`                   |
| Criteria | `LoadCriteria`          | Interface for defining load shedding criteria.       | `&CPULoadCriteria{...}` |

## LoadCriteria

LoadCriteria is an interface in the LoadShed middleware that defines the criteria for determining when to shed load in the system. Different implementations of this interface can use various metrics and algorithms to decide when and how to shed incoming requests to maintain system performance.

### CPULoadCriteria

`CPULoadCriteria` is an implementation of the `LoadCriteria` interface, using CPU load as the metric for determining whether to shed requests.

#### Properties

| Property       | Type               | Description                                                                                                                           |
| :------------- | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
| LowerThreshold | `float64`          | The lower CPU usage threshold as a fraction (0.0 to 1.0). Requests are considered for shedding when CPU usage exceeds this threshold. |
| UpperThreshold | `float64`          | The upper CPU usage threshold as a fraction (0.0 to 1.0). All requests are shed when CPU usage exceeds this threshold.                |
| Interval       | `time.Duration`    | The time interval over which the CPU usage is averaged for decision making.                                                           |
| Getter         | `CPUPercentGetter` | Interface to retrieve CPU usage percentages.                                                                                          |

#### How It Works

`CPULoadCriteria` determines the load on the system based on CPU usage and decides whether to shed incoming requests. It operates on the following principles:

- **CPU Usage Measurement**: It measures the CPU usage over a specified interval.
- **Thresholds**: Utilizes `LowerThreshold` and `UpperThreshold` values to decide when to start shedding requests.
- **Proportional Rejection Probability**:
  - **Below `LowerThreshold`**: No requests are rejected, as the system is considered under acceptable load.
  - **Between `LowerThreshold` and `UpperThreshold`**: The probability of rejecting a request increases as the CPU usage approaches the `UpperThreshold`. This is calculated using the formula:
    ```plaintext
    rejectionProbability := (cpuUsage - LowerThreshold*100) / (UpperThreshold - LowerThreshold)
    ```
  - **Above `UpperThreshold`**: All requests are rejected to prevent system overload.

This mechanism ensures that the system can adaptively manage its load, maintaining stability and performance under varying traffic conditions.

## Default Config

This is the default configuration for `LoadCriteria` in the LoadShed middleware.

```go
var ConfigDefault = Config{
  Next: nil,
  Criteria: &CPULoadCriteria{
    LowerThreshold: 0.90,  // 90% CPU usage as the start point for considering shedding
    UpperThreshold: 0.95,  // 95% CPU usage as the point where all requests are shed
    Interval:       10 * time.Second,  // CPU usage is averaged over 10 seconds
    Getter:         &DefaultCPUPercentGetter{},  // Default method for getting CPU usage
  },
}
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/jwt/README.md

---
id: jwt
---

# JWT


[](https://gofiber.io/discord)


JWT returns a JSON Web Token (JWT) auth middleware.
For valid token, it sets the user in Ctx.Locals and calls next handler.
For invalid token, it returns "401 - Unauthorized" error.
For missing token, it returns "400 - Bad Request" error.

Special thanks and credits to [Echo](https://echo.labstack.com/middleware/jwt)

**Note: Requires Go 1.19 and above**

## Install

This middleware supports Fiber v1 & v2, install accordingly.

```bash
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/jwt
go get -u github.com/golang-jwt/jwt/v5
```

## Signature

```go
jwtware.New(config ...jwtware.Config) func(*fiber.Ctx) error
```

## Config

| Property           | Type                                 | Description                                                                                                                                                                                                                                                            | Default                      |
|--------------------|--------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|
| Filter             | `func(*fiber.Ctx) bool`              | Function to skip middleware execution for specific requests. Optional.                                                                                                                                                                                                 | `nil`                        |
| SuccessHandler     | `fiber.Handler`                      | Handler executed when a token is successfully validated. Optional.                                                                                                                                                                                                     | `nil`                        |
| ErrorHandler       | `fiber.ErrorHandler`                 | Handler executed when token validation fails. Allows customization of JWT error responses. Optional.                                                                                                                                                                   | `401 Invalid or expired JWT` |
| SigningKey         | `SigningKey`                         | Primary key used to validate tokens. Used as a fallback if SigningKeys is empty. At least one of KeyFunc, JWKSetURLs, SigningKeys, or SigningKey is required.                                                                                                          | `nil`                        |
| SigningKeys        | `map[string]SigningKey`              | Map of keys used to validate tokens with the "kid" field. At least one of KeyFunc, JWKSetURLs, SigningKeys, or SigningKey is required.                                                                                                                                 | `nil`                        |
| ContextKey         | `string`                             | Key used to store user information in the context. Optional.                                                                                                                                                                                                           | `"user"`                     |
| Claims             | `jwt.Claims`                         | Defines the structure of token claims. Extendable for custom claims data. Optional.                                                                                                                                                                                    | `jwt.MapClaims{}`            |
| TokenLookup        | `string`                             | Specifies how to extract the token from the request. Format: `":<name>"` (e.g., `"header:Authorization"`, `"query:token"`, `"param:token"`, `"cookie:token"`). Optional.                                                                                                 | `"header:Authorization"`     |
| TokenProcessorFunc | `func(token string) (string, error)` | Processes the token extracted using `TokenLookup`. Optional.                                                                                                                                                                                                           | `nil`                        |
| AuthScheme         | `string`                             | Scheme used in the Authorization header. Only used with the default TokenLookup. Optional.                                                                                                                                                                             | `"Bearer"`                   |
| KeyFunc            | `func() jwt.Keyfunc`                 | Provides the public key for JWT verification, handling algorithm verification and key selection. At least one of KeyFunc, JWKSetURLs, SigningKeys, or SigningKey is required.                                                                                          | `jwtKeyFunc`                 |
| JWKSetURLs         | `[]string`                           | List of URLs containing JSON Web Key Sets (JWKS) for signature verification. HTTPS is recommended. The "kid" field is mandatory in both the JWT header and the JWKS. Default behavior includes hourly refresh, auto-refresh on new "kid", rate limiting, and timeouts. | `nil`                        |

## HS256 Example

```go
package main

import (
 "time"

 "github.com/gofiber/fiber/v2"

 jwtware "github.com/gofiber/contrib/jwt"
 "github.com/golang-jwt/jwt/v5"
)

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

 // Login route
 app.Post("/login", login)

 // Unauthenticated route
 app.Get("/", accessible)

 // JWT Middleware
 app.Use(jwtware.New(jwtware.Config{
  SigningKey: jwtware.SigningKey{Key: []byte("secret")},
 }))

 // Restricted Routes
 app.Get("/restricted", restricted)

 app.Listen(":3000")
}

func login(c *fiber.Ctx) error {
 user := c.FormValue("user")
 pass := c.FormValue("pass")

 // Throws Unauthorized error
 if user != "john" || pass != "doe" {
  return c.SendStatus(fiber.StatusUnauthorized)
 }

 // Create the Claims
 claims := jwt.MapClaims{
  "name":  "John Doe",
  "admin": true,
  "exp":   time.Now().Add(time.Hour * 72).Unix(),
 }

 // Create token
 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

 // Generate encoded token and send it as response.
 t, err := token.SignedString([]byte("secret"))
 if err != nil {
  return c.SendStatus(fiber.StatusInternalServerError)
 }

 return c.JSON(fiber.Map{"token": t})
}

func accessible(c *fiber.Ctx) error {
 return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
 user := c.Locals("user").(*jwt.Token)
 claims := user.Claims.(jwt.MapClaims)
 name := claims["name"].(string)
 return c.SendString("Welcome " + name)
}

```

## HS256 Test

_Login using username and password to retrieve a token._

```bash
curl --data "user=john&pass=doe" http://localhost:3000/login
```

_Response_

```json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
}
```

_Request a restricted resource using the token in Authorization request header._

```bash
curl localhost:3000/restricted -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
```

_Response_

```text
Welcome John Doe
```

## RS256 Example

```
/* Detailed source-code truncated for AI context efficiency. */
```

## RS256 Test

The RS256 is actually identical to the HS256 test above.

## JWK Set Test

The tests are identical to basic `JWT` tests above, with exception that `JWKSetURLs` to valid public keys collection in JSON Web Key (JWK) Set format should be supplied. See [RFC 7517](https://www.rfc-editor.org/rfc/rfc7517).

## Custom KeyFunc example

KeyFunc defines a user-defined function that supplies the public key for a token validation.
The function shall take care of verifying the signing algorithm and selecting the proper key.
A user-defined KeyFunc can be useful if tokens are issued by an external party.

When a user-defined KeyFunc is provided, SigningKey, SigningKeys, and SigningMethod are ignored.
This is one of the three options to provide a token validation key.
The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
Required if neither SigningKeys nor SigningKey is provided.
Default to an internal implementation verifying the signing algorithm and selecting the proper key.

```go
package main

import (
 "fmt"
  "github.com/gofiber/fiber/v2"

  jwtware "github.com/gofiber/contrib/jwt"
  "github.com/golang-jwt/jwt/v5"
)

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

 app.Use(jwtware.New(jwtware.Config{
  KeyFunc: customKeyFunc(),
 }))

 app.Get("/ok", func(c *fiber.Ctx) error {
  return c.SendString("OK")
 })
}

func customKeyFunc() jwt.Keyfunc {
 return func(t *jwt.Token) (interface{}, error) {
  // Always check the signing method
  if t.Method.Alg() != jwtware.HS256 {
   return nil, fmt.Errorf("Unexpected jwt signing method=%v", t.Header["alg"])
  }

  // TODO custom implementation of loading signing key like from a database
    signingKey := "secret"

  return []byte(signingKey), nil
 }
}
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/hcaptcha/README.md

---
id: hcaptcha
---

# HCaptcha


[](https://gofiber.io/discord)


A simple [HCaptcha](https://hcaptcha.com) middleware to prevent bot attacks.

:::note

Requires Go **1.21** and above

:::

## Install

:::caution

This middleware only supports Fiber **v3**.

:::

```shell
go get -u github.com/gofiber/fiber/v3
go get -u github.com/gofiber/contrib/hcaptcha
```

## Signature

```go
hcaptcha.New(config hcaptcha.Config) fiber.Handler
```

## Config

| Property        | Type                              | Description                                                                                                                                                                                          | Default                               |
|:----------------|:----------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------|
| SecretKey       | `string`                          | The secret key you obtained from the HCaptcha admin panel. This field must not be empty.                                                                                                             | `""`                                  |
| ResponseKeyFunc | `func(fiber.Ctx) (string, error)` | ResponseKeyFunc should return the token that captcha provides upon successful solving. By default, it gets the token from the body by parsing a JSON request and returns the `hcaptcha_token` field. | `hcaptcha.DefaultResponseKeyFunc`     |
| SiteVerifyURL   | `string`                          | This property specifies the API resource used for token authentication.                                                                                                                              | `https://api.hcaptcha.com/siteverify` |

## Example

```go
package main

import (
    "github.com/gofiber/contrib/hcaptcha"
    "github.com/gofiber/fiber/v3"
    "log"
)

const (
    TestSecretKey = "0x0000000000000000000000000000000000000000"
    TestSiteKey   = "20000000-ffff-ffff-ffff-000000000002"
)

func main() {
    app := fiber.New()
    captcha := hcaptcha.New(hcaptcha.Config{
        // Must set the secret key
        SecretKey: TestSecretKey,
    })
	
    app.Get("/api/", func(c fiber.Ctx) error {
        return c.JSON(fiber.Map{
            "hcaptcha_site_key": TestSiteKey,
        })
    })
	
    app.Post("/api/robots-excluded", func(c fiber.Ctx) error {
        return c.SendString("You are not a robot")
    }, captcha)
	
    log.Fatal(app.Listen(":3000"))
}
```

---

## File: contrib_versioned_docs/version-websocket_v1.x.x/fiberzerolog/README.md

---
id: fiberzerolog
---

# Fiberzerolog


[](https://gofiber.io/discord)


[Zerolog](https://zerolog.io/) logging support for Fiber.

**Note: Requires Go 1.18 and above**

## Install

This middleware supports Fiber v2.

```sh
go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/fiberzerolog
go get -u github.com/rs/zerolog/log
```

## Signature

```go
fiberzerolog.New(config ...fiberzerolog.Config) fiber.Handler
```

## Config

| Property      | Type                           | Description                                                                                                                                                                                                                                                                                 | Default                                                                     |
|:--------------|:-------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------|
| Next          | `func(*Ctx) bool`              | Define a function to skip this middleware when returned true                                                                                                                                                                                                                                | `nil`                                                                       |
| Logger        | `*zerolog.Logger`               | Add custom zerolog logger.                                                                                                                                                                                                                                                                  | `zerolog.New(os.Stderr).With().Timestamp().Logger()`                                                      |
| GetLogger        | `func(*fiber.Ctx) zerolog.Logger`           | Get custom zerolog logger, if it's defined the returned logger will replace the `Logger` value.                                                                                                                                                                                             | `nil`                                                      |
| Fields        | `[]string`                     | Add fields what you want see.                                                                                                                                                                                                                                                               | `[]string{"latency", "status", "method", "url", "error"}`                            |
| WrapHeaders   | bool                           | Wrap headers to dictionary.If false: `{"method":"POST", "header-key":"header value"}`If true: `{"method":"POST", "reqHeaders": {"header-key":"header value"}}`                                                                                                                  | `false` |
| FieldsSnakeCase   | bool                       | Use snake case for fields: FieldResBody, FieldQueryParams, FieldBytesReceived, FieldBytesSent, FieldRequestId, FieldReqHeaders, FieldResHeaders.If false: `{"method":"POST", "resBody":"v", "queryParams":"v"}`If true: `{"method":"POST", "res_body":"v", "query_params":"v"}` | `false` |
| Messages      | `[]string`                     | Custom response messages.                                                                                                                                                                                                                                                                   | `[]string{"Server error", "Client error", "Success"}`                       |
| Levels        | `[]zerolog.Level`              | Custom response levels.                                                                                                                                                                                                                                                                     | `[]zerolog.Level{zerolog.ErrorLevel, zerolog.WarnLevel, zerolog.InfoLevel}` |
| SkipURIs      | `[]string`                     | Skip logging these URI.                                                                                                                                                                                                                                                                     | `[]string{}`                                                                |
| GetResBody    | func(c *fiber.Ctx) []byte      | Define a function to get response body when return non-nil.eg: When use compress middleware, resBody is unreadable. you can set GetResBody func to get readable resBody.                                                                                                              | `nil` |

## Example

```go
package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/contrib/fiberzerolog"
    "github.com/rs/zerolog"
)

func main() {
    app := fiber.New()
    logger := zerolog.New(os.Stderr).With().Timestamp().Logger()

    app.Use(fiberzerolog.New(fiberzerolog.Config{
        Logger: &logger,
    }))

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

    if err := app.Listen(":3000"); err != nil {
        logger.Fatal().Err(err).Msg("Fiber app error")
    }
}
```