mirror of https://github.com/gofiber/fiber.git
📚 Doc: Updates to API documentation and README (#3205)
* Updates to documentation * Update .github/README.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Remove trailing spaces * Updates based on PR comments * Update docs/api/bind.md * Update docs/api/redirect.md --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: RW <rene@gofiber.io>pull/3209/head
parent
f725ded92b
commit
a12ca10cac
|
@ -39,7 +39,7 @@ Fiber v3 is currently in beta and under active development. While it offers exci
|
|||
|
||||
## ⚙️ Installation
|
||||
|
||||
Fiber requires **Go version `1.22` 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:
|
||||
Fiber requires **Go version `1.22` 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
|
||||
|
@ -59,7 +59,7 @@ This command fetches the Fiber package and adds it to your project's dependencie
|
|||
|
||||
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
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -133,7 +133,16 @@ Listed below are some of the common examples. If you want to see more code examp
|
|||
|
||||
### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
|
@ -169,23 +178,33 @@ func main() {
|
|||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### 📖 [**Route Naming**](https://docs.gofiber.io/api/app#name)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"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
|
||||
}).Name("api")
|
||||
|
||||
data, _ := json.MarshalIndent(app.GetRoute("api"), "", " ")
|
||||
fmt.Print(string(data))
|
||||
route := app.GetRoute("api")
|
||||
|
||||
data, _ := json.MarshalIndent(route, "", " ")
|
||||
fmt.Println(string(data))
|
||||
// Prints:
|
||||
// {
|
||||
// "method": "GET",
|
||||
|
@ -198,15 +217,24 @@ func main() {
|
|||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/api/app#static)
|
||||
|
||||
```go
|
||||
```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
|
||||
|
@ -215,27 +243,36 @@ func main() {
|
|||
// => 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
|
||||
// => http://localhost:3000/any/path/shows/index.html
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### 📖 [**Middleware & Next**](https://docs.gofiber.io/api/ctx#next)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Match any route
|
||||
// Middleware that matches any route
|
||||
app.Use(func(c fiber.Ctx) error {
|
||||
fmt.Println("🥇 First handler")
|
||||
return c.Next()
|
||||
})
|
||||
|
||||
// Match all routes starting with /api
|
||||
// Middleware that matches all routes starting with /api
|
||||
app.Use("/api", func(c fiber.Ctx) error {
|
||||
fmt.Println("🥈 Second handler")
|
||||
return c.Next()
|
||||
|
@ -249,13 +286,12 @@ func main() {
|
|||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>📚 Show more code examples</summary>
|
||||
|
||||
### Views engines
|
||||
### Views Engines
|
||||
|
||||
📖 [Config](https://docs.gofiber.io/api/fiber#config)
|
||||
📖 [Engines](https://github.com/gofiber/template)
|
||||
|
@ -263,11 +299,9 @@ func main() {
|
|||
|
||||
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..
|
||||
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.
|
||||
|
||||
Checkout our [Template](https://github.com/gofiber/template) package that support multiple view engines.
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -278,12 +312,12 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
// You can setup Views engine before initiation app:
|
||||
// Initialize a new Fiber app with Pug template engine
|
||||
app := fiber.New(fiber.Config{
|
||||
Views: pug.New("./views", ".pug"),
|
||||
})
|
||||
|
||||
// And now, you can call template `./views/home.pug` like this:
|
||||
// Define a route that renders the "home.pug" template
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
return c.Render("home", fiber.Map{
|
||||
"title": "Homepage",
|
||||
|
@ -295,24 +329,32 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
### Grouping routes into chains
|
||||
### Grouping Routes into Chains
|
||||
|
||||
📖 [Group](https://docs.gofiber.io/api/app#group)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func middleware(c fiber.Ctx) error {
|
||||
fmt.Println("Don't mind me!")
|
||||
log.Println("Middleware executed")
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
func handler(c fiber.Ctx) error {
|
||||
return c.SendString(c.Path())
|
||||
return c.SendString("Handler response")
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Root API route
|
||||
// Root API group with middleware
|
||||
api := app.Group("/api", middleware) // /api
|
||||
|
||||
// API v1 routes
|
||||
|
@ -325,16 +367,15 @@ func main() {
|
|||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
// ...
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Middleware logger
|
||||
### Middleware Logger
|
||||
|
||||
📖 [Logger](https://docs.gofiber.io/api/middleware/logger)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
|
@ -347,9 +388,13 @@ import (
|
|||
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"))
|
||||
}
|
||||
|
@ -359,7 +404,9 @@ func main() {
|
|||
|
||||
📖 [CORS](https://docs.gofiber.io/api/middleware/cors)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
|
@ -370,9 +417,13 @@ import (
|
|||
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"))
|
||||
}
|
||||
|
@ -384,28 +435,36 @@ Check CORS by passing any domain in `Origin` header:
|
|||
curl -H "Origin: http://example.com" --verbose http://localhost:3000
|
||||
```
|
||||
|
||||
### Custom 404 response
|
||||
### Custom 404 Response
|
||||
|
||||
📖 [HTTP Methods](https://docs.gofiber.io/api/ctx#status)
|
||||
|
||||
```go
|
||||
```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!")
|
||||
return c.SendString("This is a demo page!")
|
||||
})
|
||||
|
||||
app.Post("/register", func(c fiber.Ctx) error {
|
||||
return c.SendString("Welcome!")
|
||||
return c.SendString("Registration successful!")
|
||||
})
|
||||
|
||||
// Last middleware to match anything
|
||||
// Middleware to handle 404 Not Found
|
||||
app.Use(func(c fiber.Ctx) error {
|
||||
return c.SendStatus(404)
|
||||
// => 404 "Not Found"
|
||||
return c.SendStatus(fiber.StatusNotFound) // => 404 "Not Found"
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
|
@ -416,7 +475,15 @@ func main() {
|
|||
|
||||
📖 [JSON](https://docs.gofiber.io/api/ctx#json)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
|
@ -425,11 +492,13 @@ type User struct {
|
|||
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,
|
||||
|
@ -446,7 +515,9 @@ func main() {
|
|||
|
||||
📖 [Websocket](https://github.com/gofiber/websocket)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
|
@ -455,26 +526,31 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||
for {
|
||||
mt, msg, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("read:", err)
|
||||
break
|
||||
}
|
||||
log.Printf("recv: %s", msg)
|
||||
err = c.WriteMessage(mt, msg)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}))
|
||||
// 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)
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
// ws://localhost:3000/ws
|
||||
// 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
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -482,42 +558,46 @@ func main() {
|
|||
|
||||
📖 [More Info](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
app := fiber.New()
|
||||
|
||||
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")
|
||||
// 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(fasthttp.StreamWriter(func(w *bufio.Writer) {
|
||||
fmt.Println("WRITER")
|
||||
var i int
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
|
||||
w.Flush()
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
}))
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -525,7 +605,9 @@ func main() {
|
|||
|
||||
📖 [Recover](https://docs.gofiber.io/api/middleware/recover)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
|
@ -536,8 +618,10 @@ import (
|
|||
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")
|
||||
})
|
||||
|
@ -546,13 +630,13 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Using Trusted Proxy
|
||||
|
||||
📖 [Config](https://docs.gofiber.io/api/fiber#config)
|
||||
|
||||
```go
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
|
@ -561,13 +645,20 @@ import (
|
|||
|
||||
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{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
|
||||
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"))
|
||||
}
|
||||
```
|
||||
|
@ -583,14 +674,14 @@ Here is a list of middleware that are included within the Fiber framework.
|
|||
| [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`. |
|
||||
| [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 variants in the JSON format. |
|
||||
| [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. |
|
||||
|
@ -606,7 +697,7 @@ Here is a list of middleware that are included within the Fiber framework.
|
|||
| [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**. |
|
||||
| [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
|
||||
|
@ -615,13 +706,13 @@ List of externally hosted middleware modules and maintained by the [Fiber team](
|
|||
|
||||
| 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 `v3` Go version 1.22 or higher is required. |
|
||||
| [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 `v3`. Go version 1.22 or higher is required. |
|
||||
|
||||
## 🕶️ Awesome List
|
||||
|
||||
For more articles, middlewares, examples or tools check our [awesome list](https://github.com/gofiber/awesome-fiber).
|
||||
For more articles, middlewares, examples, or tools, check our [awesome list](https://github.com/gofiber/awesome-fiber).
|
||||
|
||||
## 👍 Contribute
|
||||
|
||||
|
@ -629,12 +720,12 @@ 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/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 personal blog.
|
||||
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 donating a [cup of coffee](https://buymeacoff.ee/fenny).
|
||||
|
||||
## 🖥️ Development
|
||||
## 💻 Development
|
||||
|
||||
To ensure your contributions are ready for a Pull Request, please use the following `Makefile` commands. These tools help maintain code quality, consistency.
|
||||
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.
|
||||
|
@ -649,22 +740,22 @@ Run these commands to ensure your code adheres to project standards and best pra
|
|||
|
||||
## ☕ 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, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
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, you can ☕ [**buy a coffee here**](https://buymeacoff.ee/fenny).
|
||||
|
||||
| | User | Donation |
|
||||
| :--------------------------------------------------------- | :----------------------------------------------- | :------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
| ---------------------------------------------------------- | ------------------------------------------------ | -------- |
|
||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||
|
|
477
docs/api/app.md
477
docs/api/app.md
|
@ -17,18 +17,28 @@ import RoutingHandler from './../partials/routing/handler.md';
|
|||
|
||||
### Mounting
|
||||
|
||||
You can Mount Fiber instance using the [`app.Use`](./app.md#use) method similar to [`express`](https://expressjs.com/en/api.html#router.use).
|
||||
You can mount a Fiber instance using the [`app.Use`](./app.md#use) method, similar to [`Express`](https://expressjs.com/en/api.html#router.use).
|
||||
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
```go title="Examples"
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
micro := fiber.New()
|
||||
|
||||
// Mount the micro app on the "/john" route
|
||||
app.Use("/john", micro) // GET /john/doe -> 200 OK
|
||||
|
||||
|
||||
micro.Get("/doe", func(c fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
@ -41,7 +51,15 @@ The `MountPath` property contains one or more path patterns on which a sub-app w
|
|||
func (app *App) MountPath() string
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
one := fiber.New()
|
||||
|
@ -51,16 +69,17 @@ func main() {
|
|||
two.Use("/three", three)
|
||||
one.Use("/two", two)
|
||||
app.Use("/one", one)
|
||||
|
||||
one.MountPath() // "/one"
|
||||
two.MountPath() // "/one/two"
|
||||
three.MountPath() // "/one/two/three"
|
||||
app.MountPath() // ""
|
||||
|
||||
fmt.Println("Mount paths:")
|
||||
fmt.Println("one.MountPath():", one.MountPath()) // "/one"
|
||||
fmt.Println("two.MountPath():", two.MountPath()) // "/one/two"
|
||||
fmt.Println("three.MountPath():", three.MountPath()) // "/one/two/three"
|
||||
fmt.Println("app.MountPath():", app.MountPath()) // ""
|
||||
}
|
||||
```
|
||||
|
||||
:::caution
|
||||
Mounting order is important for MountPath. If you want to get mount paths properly, you should start mounting from the deepest app.
|
||||
Mounting order is important for `MountPath`. To get mount paths properly, you should start mounting from the deepest app.
|
||||
:::
|
||||
|
||||
### Group
|
||||
|
@ -71,21 +90,33 @@ You can group routes by creating a `*Group` struct.
|
|||
func (app *App) Group(prefix string, handlers ...Handler) Router
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
app := fiber.New()
|
||||
|
||||
api := app.Group("/api", handler) // /api
|
||||
api := app.Group("/api", handler) // /api
|
||||
|
||||
v1 := api.Group("/v1", handler) // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
v1 := api.Group("/v1", handler) // /api/v1
|
||||
v1.Get("/list", handler) // /api/v1/list
|
||||
v1.Get("/user", handler) // /api/v1/user
|
||||
|
||||
v2 := api.Group("/v2", handler) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
v2 := api.Group("/v2", handler) // /api/v2
|
||||
v2.Get("/list", handler) // /api/v2/list
|
||||
v2.Get("/user", handler) // /api/v2/user
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
|
||||
func handler(c fiber.Ctx) error {
|
||||
return c.SendString("Handler response")
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -104,64 +135,73 @@ func (app *App) Route(path string) Register
|
|||
|
||||
```go
|
||||
type Register interface {
|
||||
All(handler Handler, middleware ...Handler) Register
|
||||
Get(handler Handler, middleware ...Handler) Register
|
||||
Head(handler Handler, middleware ...Handler) Register
|
||||
Post(handler Handler, middleware ...Handler) Register
|
||||
Put(handler Handler, middleware ...Handler) Register
|
||||
Delete(handler Handler, middleware ...Handler) Register
|
||||
Connect(handler Handler, middleware ...Handler) Register
|
||||
Options(handler Handler, middleware ...Handler) Register
|
||||
Trace(handler Handler, middleware ...Handler) Register
|
||||
Patch(handler Handler, middleware ...Handler) Register
|
||||
All(handler Handler, middleware ...Handler) Register
|
||||
Get(handler Handler, middleware ...Handler) Register
|
||||
Head(handler Handler, middleware ...Handler) Register
|
||||
Post(handler Handler, middleware ...Handler) Register
|
||||
Put(handler Handler, middleware ...Handler) Register
|
||||
Delete(handler Handler, middleware ...Handler) Register
|
||||
Connect(handler Handler, middleware ...Handler) Register
|
||||
Options(handler Handler, middleware ...Handler) Register
|
||||
Trace(handler Handler, middleware ...Handler) Register
|
||||
Patch(handler Handler, middleware ...Handler) Register
|
||||
|
||||
Add(methods []string, handler Handler, middleware ...Handler) Register
|
||||
Add(methods []string, handler Handler, middleware ...Handler) Register
|
||||
|
||||
Route(path string) Register
|
||||
Route(path string) Register
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
```go title="Examples"
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
app := fiber.New()
|
||||
|
||||
// use `Route` as chainable route declaration method
|
||||
app.Route("/test").Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /test")
|
||||
})
|
||||
|
||||
app.Route("/events").all(func(c fiber.Ctx) error {
|
||||
// runs for all HTTP verbs first
|
||||
// think of it as route specific middleware!
|
||||
})
|
||||
.get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /events")
|
||||
})
|
||||
.post(func(c fiber.Ctx) error {
|
||||
// maybe add a new event...
|
||||
})
|
||||
|
||||
// combine multiple routes
|
||||
app.Route("/v2").Route("/user").Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /v2/user")
|
||||
})
|
||||
|
||||
// use multiple methods
|
||||
app.Route("/api").Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /api")
|
||||
}).Post(func(c fiber.Ctx) error {
|
||||
return c.SendString("POST /api")
|
||||
})
|
||||
// Use `Route` as a chainable route declaration method
|
||||
app.Route("/test").Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /test")
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
app.Route("/events").All(func(c fiber.Ctx) error {
|
||||
// Runs for all HTTP verbs first
|
||||
// Think of it as route-specific middleware!
|
||||
}).
|
||||
Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /events")
|
||||
}).
|
||||
Post(func(c fiber.Ctx) error {
|
||||
// Maybe add a new event...
|
||||
return c.SendString("POST /events")
|
||||
})
|
||||
|
||||
// Combine multiple routes
|
||||
app.Route("/v2").Route("/user").Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /v2/user")
|
||||
})
|
||||
|
||||
// Use multiple methods
|
||||
app.Route("/api").Get(func(c fiber.Ctx) error {
|
||||
return c.SendString("GET /api")
|
||||
}).Post(func(c fiber.Ctx) error {
|
||||
return c.SendString("POST /api")
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
### HandlersCount
|
||||
|
||||
This method returns the amount of registered handlers.
|
||||
This method returns the number of registered handlers.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) HandlersCount() uint32
|
||||
|
@ -169,13 +209,22 @@ func (app *App) HandlersCount() uint32
|
|||
|
||||
### Stack
|
||||
|
||||
This method returns the original router stack
|
||||
This method returns the original router stack.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Stack() [][]*Route
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
var handler = func(c fiber.Ctx) error { return nil }
|
||||
|
||||
func main() {
|
||||
|
@ -187,7 +236,7 @@ func main() {
|
|||
data, _ := json.MarshalIndent(app.Stack(), "", " ")
|
||||
fmt.Println(string(data))
|
||||
|
||||
app.Listen(":3000")
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -228,25 +277,32 @@ func main() {
|
|||
|
||||
### Name
|
||||
|
||||
This method assigns the name of latest created route.
|
||||
This method assigns the name to the latest created route.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Name(name string) Router
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
var handler = func(c fiber.Ctx) error { return nil }
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var handler = func(c fiber.Ctx) error { return nil }
|
||||
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", handler)
|
||||
app.Name("index")
|
||||
|
||||
app.Get("/doe", handler).Name("home")
|
||||
|
||||
app.Trace("/tracer", handler).Name("tracert")
|
||||
|
||||
app.Delete("/delete", handler).Name("delete")
|
||||
|
||||
a := app.Group("/a")
|
||||
|
@ -255,10 +311,9 @@ func main() {
|
|||
a.Get("/test", handler).Name("test")
|
||||
|
||||
data, _ := json.MarshalIndent(app.Stack(), "", " ")
|
||||
fmt.Print(string(data))
|
||||
|
||||
app.Listen(":3000")
|
||||
fmt.Println(string(data))
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -335,25 +390,34 @@ func main() {
|
|||
|
||||
### GetRoute
|
||||
|
||||
This method gets the route by name.
|
||||
This method retrieves a route by its name.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) GetRoute(name string) Route
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
var handler = func(c fiber.Ctx) error { return nil }
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/", handler).Name("index")
|
||||
|
||||
data, _ := json.MarshalIndent(app.GetRoute("index"), "", " ")
|
||||
fmt.Print(string(data))
|
||||
route := app.GetRoute("index")
|
||||
|
||||
data, _ := json.MarshalIndent(route, "", " ")
|
||||
fmt.Println(string(data))
|
||||
|
||||
app.Listen(":3000")
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -373,22 +437,38 @@ func main() {
|
|||
|
||||
### GetRoutes
|
||||
|
||||
This method gets all routes.
|
||||
This method retrieves all routes.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) GetRoutes(filterUseOption ...bool) []Route
|
||||
```
|
||||
|
||||
When filterUseOption equal to true, it will filter the routes registered by the middleware.
|
||||
When `filterUseOption` is set to `true`, it filters out routes registered by middleware.
|
||||
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
```go title="Examples"
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
app.Post("/", func (c fiber.Ctx) error {
|
||||
|
||||
app.Post("/", func(c fiber.Ctx) error {
|
||||
return c.SendString("Hello, World!")
|
||||
}).Name("index")
|
||||
data, _ := json.MarshalIndent(app.GetRoutes(true), "", " ")
|
||||
fmt.Print(string(data))
|
||||
|
||||
routes := app.GetRoutes(true)
|
||||
|
||||
data, _ := json.MarshalIndent(routes, "", " ")
|
||||
fmt.Println(string(data))
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -410,7 +490,7 @@ func main() {
|
|||
|
||||
## Config
|
||||
|
||||
Config returns the [app config](./fiber.md#config) as value \( read-only \).
|
||||
`Config` returns the [app config](./fiber.md#config) as a value (read-only).
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Config() Config
|
||||
|
@ -418,7 +498,7 @@ func (app *App) Config() Config
|
|||
|
||||
## Handler
|
||||
|
||||
Handler returns the server handler that can be used to serve custom [`\*fasthttp.RequestCtx`](https://pkg.go.dev/github.com/valyala/fasthttp#RequestCtx) requests.
|
||||
`Handler` returns the server handler that can be used to serve custom [`\*fasthttp.RequestCtx`](https://pkg.go.dev/github.com/valyala/fasthttp#RequestCtx) requests.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Handler() fasthttp.RequestHandler
|
||||
|
@ -426,7 +506,7 @@ func (app *App) Handler() fasthttp.RequestHandler
|
|||
|
||||
## ErrorHandler
|
||||
|
||||
Errorhandler executes the process which was defined for the application in case of errors, this is used in some cases in middlewares.
|
||||
`ErrorHandler` executes the process defined for the application in case of errors. This is used in some cases in middlewares.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) ErrorHandler(ctx Ctx, err error) error
|
||||
|
@ -434,15 +514,23 @@ func (app *App) ErrorHandler(ctx Ctx, err error) error
|
|||
|
||||
## NewCtxFunc
|
||||
|
||||
NewCtxFunc allows to customize the ctx struct as we want.
|
||||
`NewCtxFunc` allows you to customize the `ctx` struct as needed.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) NewCtxFunc(function func(app *App) CustomCtx)
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
type CustomCtx struct {
|
||||
DefaultCtx
|
||||
fiber.DefaultCtx
|
||||
}
|
||||
|
||||
// Custom method
|
||||
|
@ -450,86 +538,102 @@ func (c *CustomCtx) Params(key string, defaultValue ...string) string {
|
|||
return "prefix_" + c.DefaultCtx.Params(key)
|
||||
}
|
||||
|
||||
app := New()
|
||||
app.NewCtxFunc(func(app *fiber.App) fiber.CustomCtx {
|
||||
return &CustomCtx{
|
||||
DefaultCtx: *NewDefaultCtx(app),
|
||||
}
|
||||
})
|
||||
// curl http://localhost:3000/123
|
||||
app.Get("/:id", func(c Ctx) error {
|
||||
// use custom method - output: prefix_123
|
||||
return c.SendString(c.Params("id"))
|
||||
})
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.NewCtxFunc(func(app *fiber.App) fiber.CustomCtx {
|
||||
return &CustomCtx{
|
||||
DefaultCtx: *fiber.NewDefaultCtx(app),
|
||||
}
|
||||
})
|
||||
|
||||
app.Get("/:id", func(c fiber.Ctx) error {
|
||||
// Use custom method - output: prefix_123
|
||||
return c.SendString(c.Params("id"))
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
## RegisterCustomBinder
|
||||
|
||||
You can register custom binders to use as [`Bind().Custom("name")`](bind.md#custom).
|
||||
They should be compatible with CustomBinder interface.
|
||||
You can register custom binders to use with [`Bind().Custom("name")`](bind.md#custom). They should be compatible with the `CustomBinder` interface.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) RegisterCustomBinder(binder CustomBinder)
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
app := fiber.New()
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Name string `yaml:"name"`
|
||||
}
|
||||
|
||||
type customBinder struct{}
|
||||
|
||||
// My custom binder
|
||||
customBinder := &customBinder{}
|
||||
// Name of custom binder, which will be used as Bind().Custom("name")
|
||||
func (*customBinder) Name() string {
|
||||
return "custom"
|
||||
}
|
||||
// Is used in the Body Bind method to check if the binder should be used for custom mime types
|
||||
|
||||
func (*customBinder) MIMETypes() []string {
|
||||
return []string{"application/yaml"}
|
||||
}
|
||||
// Parse the body and bind it to the out interface
|
||||
func (*customBinder) Parse(c Ctx, out any) error {
|
||||
// parse yaml body
|
||||
|
||||
func (*customBinder) Parse(c fiber.Ctx, out any) error {
|
||||
// Parse YAML body
|
||||
return yaml.Unmarshal(c.Body(), out)
|
||||
}
|
||||
// Register custom binder
|
||||
app.RegisterCustomBinder(customBinder)
|
||||
|
||||
// curl -X POST http://localhost:3000/custom -H "Content-Type: application/yaml" -d "name: John"
|
||||
app.Post("/custom", func(c Ctx) error {
|
||||
var user User
|
||||
// output: {Name:John}
|
||||
// Custom binder is used by the name
|
||||
if err := c.Bind().Custom("custom", &user); err != nil {
|
||||
return err
|
||||
}
|
||||
// ...
|
||||
return c.JSON(user)
|
||||
})
|
||||
// curl -X POST http://localhost:3000/normal -H "Content-Type: application/yaml" -d "name: Doe"
|
||||
app.Post("/normal", func(c Ctx) error {
|
||||
var user User
|
||||
// output: {Name:Doe}
|
||||
// Custom binder is used by the mime type
|
||||
if err := c.Bind().Body(&user); err != nil {
|
||||
return err
|
||||
}
|
||||
// ...
|
||||
return c.JSON(user)
|
||||
})
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Register custom binder
|
||||
app.RegisterCustomBinder(&customBinder{})
|
||||
|
||||
app.Post("/custom", func(c fiber.Ctx) error {
|
||||
var user User
|
||||
// Use Custom binder by name
|
||||
if err := c.Bind().Custom("custom", &user); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.JSON(user)
|
||||
})
|
||||
|
||||
app.Post("/normal", func(c fiber.Ctx) error {
|
||||
var user User
|
||||
// Custom binder is used by the MIME type
|
||||
if err := c.Bind().Body(&user); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.JSON(user)
|
||||
})
|
||||
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
## RegisterCustomConstraint
|
||||
|
||||
RegisterCustomConstraint allows to register custom constraint.
|
||||
`RegisterCustomConstraint` allows you to register custom constraints.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) RegisterCustomConstraint(constraint CustomConstraint)
|
||||
```
|
||||
|
||||
See [Custom Constraint](../guide/routing.md#custom-constraint) section for more information.
|
||||
See the [Custom Constraint](../guide/routing.md#custom-constraint) section for more information.
|
||||
|
||||
## SetTLSHandler
|
||||
|
||||
Use SetTLSHandler to set [ClientHelloInfo](https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2) when using TLS with Listener.
|
||||
Use `SetTLSHandler` to set [`ClientHelloInfo`](https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2) when using TLS with a `Listener`.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) SetTLSHandler(tlsHandler *TLSHandler)
|
||||
|
@ -537,38 +641,53 @@ func (app *App) SetTLSHandler(tlsHandler *TLSHandler)
|
|||
|
||||
## Test
|
||||
|
||||
Testing your application is done with the **Test** method. Use this method for creating `_test.go` files or when you need to debug your routing logic. The default timeout is `1s` if you want to disable a timeout altogether, pass `-1` as a second argument.
|
||||
Testing your application is done with the `Test` method. Use this method for creating `_test.go` files or when you need to debug your routing logic. The default timeout is `1s`; to disable a timeout altogether, pass `-1` as the second argument.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error)
|
||||
```
|
||||
|
||||
```go title="Examples"
|
||||
// Create route with GET method for test:
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
fmt.Println(c.BaseURL()) // => http://google.com
|
||||
fmt.Println(c.Get("X-Custom-Header")) // => hi
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
return c.SendString("hello, World!")
|
||||
})
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
// http.Request
|
||||
req := httptest.NewRequest("GET", "http://google.com", nil)
|
||||
req.Header.Set("X-Custom-Header", "hi")
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// http.Response
|
||||
resp, _ := app.Test(req)
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
// Create route with GET method for test:
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
fmt.Println(c.BaseURL()) // => http://google.com
|
||||
fmt.Println(c.Get("X-Custom-Header")) // => hi
|
||||
return c.SendString("hello, World!")
|
||||
})
|
||||
|
||||
// Do something with results:
|
||||
if resp.StatusCode == fiber.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
fmt.Println(string(body)) // => Hello, World!
|
||||
// Create http.Request
|
||||
req := httptest.NewRequest("GET", "http://google.com", nil)
|
||||
req.Header.Set("X-Custom-Header", "hi")
|
||||
|
||||
// Perform the test
|
||||
resp, _ := app.Test(req)
|
||||
|
||||
// Do something with the results:
|
||||
if resp.StatusCode == fiber.StatusOK {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
fmt.Println(string(body)) // => hello, World!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Hooks
|
||||
|
||||
Hooks is a method to return [hooks](./hooks.md) property.
|
||||
`Hooks` is a method to return the [hooks](./hooks.md) property.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) Hooks() *Hooks
|
||||
|
@ -576,7 +695,7 @@ func (app *App) Hooks() *Hooks
|
|||
|
||||
## RebuildTree
|
||||
|
||||
The RebuildTree method is designed to rebuild the route tree and enable dynamic route registration. It returns a pointer to the App instance.
|
||||
The `RebuildTree` method is designed to rebuild the route tree and enable dynamic route registration. It returns a pointer to the `App` instance.
|
||||
|
||||
```go title="Signature"
|
||||
func (app *App) RebuildTree() *App
|
||||
|
@ -588,16 +707,32 @@ func (app *App) RebuildTree() *App
|
|||
|
||||
Here’s an example of how to define and register routes dynamically:
|
||||
|
||||
```go
|
||||
app.Get("/define", func(c Ctx) error { // Define a new route dynamically
|
||||
app.Get("/dynamically-defined", func(c Ctx) error { // Adding a dynamically defined route
|
||||
return c.SendStatus(http.StatusOK)
|
||||
```go title="Example"
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New()
|
||||
|
||||
app.Get("/define", func(c fiber.Ctx) error {
|
||||
// Define a new route dynamically
|
||||
app.Get("/dynamically-defined", func(c fiber.Ctx) error {
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
// Rebuild the route tree to register the new route
|
||||
app.RebuildTree()
|
||||
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
})
|
||||
|
||||
app.RebuildTree() // Rebuild the route tree to register the new route
|
||||
|
||||
return c.SendStatus(http.StatusOK)
|
||||
})
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
```
|
||||
|
||||
In this example, a new route is defined and then `RebuildTree()` is called to make sure the new route is registered and available.
|
||||
In this example, a new route is defined and then `RebuildTree()` is called to ensure the new route is registered and available.
|
||||
|
|
349
docs/api/bind.md
349
docs/api/bind.md
|
@ -6,13 +6,11 @@ sidebar_position: 4
|
|||
toc_max_heading_level: 4
|
||||
---
|
||||
|
||||
Bindings are used to parse the request/response body, query parameters, cookies and much more into a struct.
|
||||
Bindings are used to parse the request/response body, query parameters, cookies, and much more into a struct.
|
||||
|
||||
:::info
|
||||
|
||||
All binder returned value are only valid within the handler. Do not store any references.
|
||||
All binder returned values are only valid within the handler. Do not store any references.
|
||||
Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation)
|
||||
|
||||
:::
|
||||
|
||||
## Binders
|
||||
|
@ -32,22 +30,21 @@ Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more..
|
|||
|
||||
Binds the request body to a struct.
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called Pass, you would use a struct field of `json:"pass"`.
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called `Pass`, you would use a struct field with `json:"pass"`.
|
||||
|
||||
| content-type | struct tag |
|
||||
| Content-Type | Struct Tag |
|
||||
| ----------------------------------- | ---------- |
|
||||
| `application/x-www-form-urlencoded` | form |
|
||||
| `multipart/form-data` | form |
|
||||
| `application/json` | json |
|
||||
| `application/xml` | xml |
|
||||
| `text/xml` | xml |
|
||||
| `application/x-www-form-urlencoded` | `form` |
|
||||
| `multipart/form-data` | `form` |
|
||||
| `application/json` | `json` |
|
||||
| `application/xml` | `xml` |
|
||||
| `text/xml` | `xml` |
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Body(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `json:"name" xml:"name" form:"name"`
|
||||
Pass string `json:"pass" xml:"pass" form:"pass"`
|
||||
|
@ -65,34 +62,35 @@ app.Post("/", func(c fiber.Ctx) error {
|
|||
|
||||
// ...
|
||||
})
|
||||
|
||||
// Run tests with the following curl commands
|
||||
|
||||
// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000
|
||||
|
||||
// curl -X POST -H "Content-Type: application/xml" --data "<login><name>john</name><pass>doe</pass></login>" localhost:3000
|
||||
|
||||
// curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000
|
||||
|
||||
// curl -X POST -F name=john -F pass=doe http://localhost:3000
|
||||
|
||||
// curl -X POST "http://localhost:3000/?name=john&pass=doe"
|
||||
```
|
||||
|
||||
**The methods for the various bodies can also be used directly:**
|
||||
Run tests with the following `curl` commands:
|
||||
|
||||
#### Form
|
||||
```bash
|
||||
# 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><pass>doe</pass></login>" localhost:3000
|
||||
|
||||
# Form URL-Encoded
|
||||
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
|
||||
```
|
||||
|
||||
### Form
|
||||
|
||||
Binds the request form body to a struct.
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a Form body with a field called Pass, you would use a struct field of `form:"pass"`.
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a form body with a field called `Pass`, you would use a struct field with `form:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Form(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `form:"name"`
|
||||
Pass string `form:"pass"`
|
||||
|
@ -110,24 +108,25 @@ app.Post("/", func(c fiber.Ctx) error {
|
|||
|
||||
// ...
|
||||
})
|
||||
|
||||
// Run tests with the following curl commands
|
||||
|
||||
// curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000
|
||||
```
|
||||
|
||||
#### JSON
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
Binds the request json body to a struct.
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" --data "name=john&pass=doe" localhost:3000
|
||||
```
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called Pass, you would use a struct field of `json:"pass"`.
|
||||
### JSON
|
||||
|
||||
Binds the request JSON body to a struct.
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a JSON body with a field called `Pass`, you would use a struct field with `json:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) JSON(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `json:"name"`
|
||||
Pass string `json:"pass"`
|
||||
|
@ -145,18 +144,19 @@ app.Post("/", func(c fiber.Ctx) error {
|
|||
|
||||
// ...
|
||||
})
|
||||
|
||||
// Run tests with the following curl commands
|
||||
|
||||
// curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000
|
||||
|
||||
```
|
||||
|
||||
#### MultipartForm
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/json" --data "{\"name\":\"john\",\"pass\":\"doe\"}" localhost:3000
|
||||
```
|
||||
|
||||
### MultipartForm
|
||||
|
||||
Binds the request multipart form body to a struct.
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a MultipartForm body with a field called Pass, you would use a struct field of `form:"pass"`.
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse a multipart form body with a field called `Pass`, you would use a struct field with `form:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) MultipartForm(out any) error
|
||||
|
@ -181,18 +181,19 @@ app.Post("/", func(c fiber.Ctx) error {
|
|||
|
||||
// ...
|
||||
})
|
||||
|
||||
// Run tests with the following curl commands
|
||||
|
||||
// curl -X POST -H "Content-Type: multipart/form-data" -F "name=john" -F "pass=doe" localhost:3000
|
||||
|
||||
```
|
||||
|
||||
#### XML
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
Binds the request xml form body to a struct.
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: multipart/form-data" -F "name=john" -F "pass=doe" localhost:3000
|
||||
```
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse an XML body with a field called Pass, you would use a struct field of `xml:"pass"`.
|
||||
### XML
|
||||
|
||||
Binds the request XML body to a struct.
|
||||
|
||||
It is important to specify the correct struct tag based on the content type to be parsed. For example, if you want to parse an XML body with a field called `Pass`, you would use a struct field with `xml:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) XML(out any) error
|
||||
|
@ -217,27 +218,28 @@ app.Post("/", func(c fiber.Ctx) error {
|
|||
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
// Run tests with the following curl commands
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
// curl -X POST -H "Content-Type: application/xml" --data "<login><name>john</name><pass>doe</pass></login>" localhost:3000
|
||||
```bash
|
||||
curl -X POST -H "Content-Type: application/xml" --data "<login><name>john</name><pass>doe</pass></login>" localhost:3000
|
||||
```
|
||||
|
||||
### Cookie
|
||||
|
||||
This method is similar to [Body-Binding](#body), but for cookie parameters.
|
||||
It is important to use the struct tag "cookie". For example, if you want to parse a cookie with a field called Age, you would use a struct field of `cookie:"age"`.
|
||||
This method is similar to [Body Binding](#body), but for cookie parameters.
|
||||
It is important to use the struct tag `cookie`. For example, if you want to parse a cookie with a field called `Age`, you would use a struct field with `cookie:"age"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Cookie(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `cookie:"name"`
|
||||
Age int `cookie:"age"`
|
||||
Job bool `cookie:"job"`
|
||||
Name string `cookie:"name"`
|
||||
Age int `cookie:"age"`
|
||||
Job bool `cookie:"job"`
|
||||
}
|
||||
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
|
@ -247,29 +249,32 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Println(p.Name) // Joseph
|
||||
log.Println(p.Age) // 23
|
||||
log.Println(p.Job) // true
|
||||
log.Println(p.Name) // Joseph
|
||||
log.Println(p.Age) // 23
|
||||
log.Println(p.Job) // true
|
||||
})
|
||||
// Run tests with the following curl command
|
||||
// curl.exe --cookie "name=Joseph; age=23; job=true" http://localhost:8000/
|
||||
```
|
||||
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
```bash
|
||||
curl --cookie "name=Joseph; age=23; job=true" http://localhost:8000/
|
||||
```
|
||||
|
||||
### Header
|
||||
|
||||
This method is similar to [Body-Binding](#body), but for request headers.
|
||||
It is important to use the struct tag "header". For example, if you want to parse a request header with a field called Pass, you would use a struct field of `header:"pass"`.
|
||||
This method is similar to [Body Binding](#body), but for request headers.
|
||||
It is important to use the struct tag `header`. For example, if you want to parse a request header with a field called `Pass`, you would use a struct field with `header:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Header(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `header:"name"`
|
||||
Pass string `header:"pass"`
|
||||
Products []string `header:"products"`
|
||||
Name string `header:"name"`
|
||||
Pass string `header:"pass"`
|
||||
Products []string `header:"products"`
|
||||
}
|
||||
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
|
@ -281,30 +286,32 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
|
||||
log.Println(p.Name) // john
|
||||
log.Println(p.Pass) // doe
|
||||
log.Println(p.Products) // [shoe, hat]
|
||||
log.Println(p.Products) // [shoe hat]
|
||||
|
||||
// ...
|
||||
})
|
||||
// Run tests with the following curl command
|
||||
```
|
||||
|
||||
// curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat"
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
```bash
|
||||
curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat"
|
||||
```
|
||||
|
||||
### Query
|
||||
|
||||
This method is similar to [Body-Binding](#body), but for query parameters.
|
||||
It is important to use the struct tag "query". For example, if you want to parse a query parameter with a field called Pass, you would use a struct field of `query:"pass"`.
|
||||
This method is similar to [Body Binding](#body), but for query parameters.
|
||||
It is important to use the struct tag `query`. For example, if you want to parse a query parameter with a field called `Pass`, you would use a struct field with `query:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Query(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `query:"name"`
|
||||
Pass string `query:"pass"`
|
||||
Products []string `query:"products"`
|
||||
Name string `query:"name"`
|
||||
Pass string `query:"pass"`
|
||||
Products []string `query:"products"`
|
||||
}
|
||||
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
|
@ -314,40 +321,41 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Println(p.Name) // john
|
||||
log.Println(p.Pass) // doe
|
||||
// fiber.Config{EnableSplittingOnParsers: false} - default
|
||||
log.Println(p.Products) // ["shoe,hat"]
|
||||
// fiber.Config{EnableSplittingOnParsers: true}
|
||||
log.Println(p.Name) // john
|
||||
log.Println(p.Pass) // doe
|
||||
// Depending on fiber.Config{EnableSplittingOnParsers: false} - default
|
||||
log.Println(p.Products) // ["shoe,hat"]
|
||||
// With fiber.Config{EnableSplittingOnParsers: true}
|
||||
// log.Println(p.Products) // ["shoe", "hat"]
|
||||
|
||||
|
||||
// ...
|
||||
})
|
||||
// Run tests with the following curl command
|
||||
```
|
||||
|
||||
// curl "http://localhost:3000/?name=john&pass=doe&products=shoe,hat"
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
```bash
|
||||
curl "http://localhost:3000/?name=john&pass=doe&products=shoe,hat"
|
||||
```
|
||||
|
||||
:::info
|
||||
For more parser settings please look here [Config](fiber.md#enablesplittingonparsers)
|
||||
For more parser settings, please refer to [Config](fiber.md#enablesplittingonparsers)
|
||||
:::
|
||||
|
||||
### RespHeader
|
||||
|
||||
This method is similar to [Body-Binding](#body), but for response headers.
|
||||
It is important to use the struct tag "respHeader". For example, if you want to parse a request header with a field called Pass, you would use a struct field of `respHeader:"pass"`.
|
||||
This method is similar to [Body Binding](#body), but for response headers.
|
||||
It is important to use the struct tag `respHeader`. For example, if you want to parse a response header with a field called `Pass`, you would use a struct field with `respHeader:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Header(out any) error
|
||||
func (b *Bind) RespHeader(out any) error
|
||||
```
|
||||
|
||||
```go title="Example"
|
||||
// Field names should start with an uppercase letter
|
||||
type Person struct {
|
||||
Name string `respHeader:"name"`
|
||||
Pass string `respHeader:"pass"`
|
||||
Products []string `respHeader:"products"`
|
||||
Name string `respHeader:"name"`
|
||||
Pass string `respHeader:"pass"`
|
||||
Products []string `respHeader:"products"`
|
||||
}
|
||||
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
|
@ -359,18 +367,22 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
|
||||
log.Println(p.Name) // john
|
||||
log.Println(p.Pass) // doe
|
||||
log.Println(p.Products) // [shoe, hat]
|
||||
log.Println(p.Products) // [shoe hat]
|
||||
|
||||
// ...
|
||||
})
|
||||
// Run tests with the following curl command
|
||||
```
|
||||
|
||||
// curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat"
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
```bash
|
||||
curl "http://localhost:3000/" -H "name: john" -H "pass: doe" -H "products: shoe,hat"
|
||||
```
|
||||
|
||||
### URI
|
||||
|
||||
This method is similar to [Body-Binding](#body), but for path parameters. It is important to use the struct tag "uri". For example, if you want to parse a path parameter with a field called Pass, you would use a struct field of uri:"pass"
|
||||
This method is similar to [Body Binding](#body), but for path parameters.
|
||||
It is important to use the struct tag `uri`. For example, if you want to parse a path parameter with a field called `Pass`, you would use a struct field with `uri:"pass"`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) URI(out any) error
|
||||
|
@ -379,20 +391,24 @@ func (b *Bind) URI(out any) error
|
|||
```go title="Example"
|
||||
// GET http://example.com/user/111
|
||||
app.Get("/user/:id", func(c fiber.Ctx) error {
|
||||
param := struct {ID uint `uri:"id"`}{}
|
||||
param := struct {
|
||||
ID uint `uri:"id"`
|
||||
}{}
|
||||
|
||||
c.Bind().URI(¶m) // "{"id": 111}"
|
||||
if err := c.Bind().URI(¶m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ...
|
||||
return c.SendString(fmt.Sprintf("User ID: %d", param.ID))
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
## Custom
|
||||
|
||||
To use custom binders, you have to use this method.
|
||||
|
||||
You can register them from [RegisterCustomBinder](./app.md#registercustombinder) method of Fiber instance.
|
||||
You can register them using the [RegisterCustomBinder](./app.md#registercustombinder) method of the Fiber instance.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Custom(name string, dest any) error
|
||||
|
@ -402,47 +418,50 @@ func (b *Bind) Custom(name string, dest any) error
|
|||
app := fiber.New()
|
||||
|
||||
// My custom binder
|
||||
customBinder := &customBinder{}
|
||||
// Name of custom binder, which will be used as Bind().Custom("name")
|
||||
func (*customBinder) Name() string {
|
||||
type customBinder struct{}
|
||||
|
||||
func (cb *customBinder) Name() string {
|
||||
return "custom"
|
||||
}
|
||||
// Is used in the Body Bind method to check if the binder should be used for custom mime types
|
||||
func (*customBinder) MIMETypes() []string {
|
||||
|
||||
func (cb *customBinder) MIMETypes() []string {
|
||||
return []string{"application/yaml"}
|
||||
}
|
||||
// Parse the body and bind it to the out interface
|
||||
func (*customBinder) Parse(c Ctx, out any) error {
|
||||
// parse yaml body
|
||||
|
||||
func (cb *customBinder) Parse(c fiber.Ctx, out any) error {
|
||||
// parse YAML body
|
||||
return yaml.Unmarshal(c.Body(), out)
|
||||
}
|
||||
|
||||
// Register custom binder
|
||||
app.RegisterCustomBinder(customBinder)
|
||||
app.RegisterCustomBinder(&customBinder{})
|
||||
|
||||
type User struct {
|
||||
Name string `yaml:"name"`
|
||||
}
|
||||
|
||||
// curl -X POST http://localhost:3000/custom -H "Content-Type: application/yaml" -d "name: John"
|
||||
app.Post("/custom", func(c Ctx) error {
|
||||
app.Post("/custom", func(c fiber.Ctx) error {
|
||||
var user User
|
||||
// output: {Name:John}
|
||||
// Custom binder is used by the name
|
||||
// Use Custom binder by name
|
||||
if err := c.Bind().Custom("custom", &user); err != nil {
|
||||
return err
|
||||
}
|
||||
// ...
|
||||
return c.JSON(user)
|
||||
})
|
||||
```
|
||||
|
||||
Internally they are also used in the [Body](#body) method.
|
||||
For this the MIMETypes method is used to check if the custom binder should be used for the given content type.
|
||||
Internally, custom binders are also used in the [Body](#body) method.
|
||||
The `MIMETypes` method is used to check if the custom binder should be used for the given content type.
|
||||
|
||||
## Options
|
||||
|
||||
For more control over the error handling, you can use the following methods.
|
||||
For more control over error handling, you can use the following methods.
|
||||
|
||||
### Must
|
||||
|
||||
If you want to handle binder errors automatically, you can use Must.
|
||||
If there's an error it'll return error and 400 as HTTP status.
|
||||
If you want to handle binder errors automatically, you can use `Must`.
|
||||
If there's an error, it will return the error and set HTTP status to `400 Bad Request`.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Must() *Bind
|
||||
|
@ -450,8 +469,8 @@ func (b *Bind) Must() *Bind
|
|||
|
||||
### Should
|
||||
|
||||
To handle binder errors manually, you can prefer Should method.
|
||||
It's default behavior of binder.
|
||||
To handle binder errors manually, you can use the `Should` method.
|
||||
It's the default behavior of the binder.
|
||||
|
||||
```go title="Signature"
|
||||
func (b *Bind) Should() *Bind
|
||||
|
@ -459,7 +478,7 @@ func (b *Bind) Should() *Bind
|
|||
|
||||
## SetParserDecoder
|
||||
|
||||
Allow you to config BodyParser/QueryParser decoder, base on schema's options, providing possibility to add custom type for parsing.
|
||||
Allows you to configure the BodyParser/QueryParser decoder based on schema options, providing the possibility to add custom types for parsing.
|
||||
|
||||
```go title="Signature"
|
||||
func SetParserDecoder(parserConfig fiber.ParserConfig{
|
||||
|
@ -477,34 +496,34 @@ func SetParserDecoder(parserConfig fiber.ParserConfig{
|
|||
|
||||
type CustomTime time.Time
|
||||
|
||||
// String() returns the time in string
|
||||
// String returns the time in string format
|
||||
func (ct *CustomTime) String() string {
|
||||
t := time.Time(*ct).String()
|
||||
return t
|
||||
}
|
||||
|
||||
// Register the converter for CustomTime type format as 2006-01-02
|
||||
var timeConverter = func(value string) reflect.Value {
|
||||
fmt.Println("timeConverter", value)
|
||||
return t
|
||||
}
|
||||
|
||||
// Converter for CustomTime type with format "2006-01-02"
|
||||
var timeConverter = func(value string) reflect.Value {
|
||||
fmt.Println("timeConverter:", value)
|
||||
if v, err := time.Parse("2006-01-02", value); err == nil {
|
||||
return reflect.ValueOf(v)
|
||||
return reflect.ValueOf(CustomTime(v))
|
||||
}
|
||||
return reflect.Value{}
|
||||
}
|
||||
|
||||
customTime := fiber.ParserType{
|
||||
Customtype: CustomTime{},
|
||||
CustomType: CustomTime{},
|
||||
Converter: timeConverter,
|
||||
}
|
||||
|
||||
// Add setting to the Decoder
|
||||
// Add custom type to the Decoder settings
|
||||
fiber.SetParserDecoder(fiber.ParserConfig{
|
||||
IgnoreUnknownKeys: true,
|
||||
ParserType: []fiber.ParserType{customTime},
|
||||
ZeroEmpty: true,
|
||||
})
|
||||
|
||||
// Example to use CustomType, you pause custom time format not in RFC3339
|
||||
// Example using CustomTime with non-RFC3339 format
|
||||
type Demo struct {
|
||||
Date CustomTime `form:"date" query:"date"`
|
||||
Title string `form:"title" query:"title"`
|
||||
|
@ -513,31 +532,38 @@ type Demo struct {
|
|||
|
||||
app.Post("/body", func(c fiber.Ctx) error {
|
||||
var d Demo
|
||||
c.BodyParser(&d)
|
||||
fmt.Println("d.Date", d.Date.String())
|
||||
if err := c.Bind().Body(&d); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("d.Date:", d.Date.String())
|
||||
return c.JSON(d)
|
||||
})
|
||||
|
||||
app.Get("/query", func(c fiber.Ctx) error {
|
||||
var d Demo
|
||||
c.QueryParser(&d)
|
||||
fmt.Println("d.Date", d.Date.String())
|
||||
if err := c.Bind().Query(&d); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("d.Date:", d.Date.String())
|
||||
return c.JSON(d)
|
||||
})
|
||||
|
||||
// curl -X POST -F title=title -F body=body -F date=2021-10-20 http://localhost:3000/body
|
||||
// Run tests with the following curl commands:
|
||||
|
||||
// curl -X GET "http://localhost:3000/query?title=title&body=body&date=2021-10-20"
|
||||
# Body Binding
|
||||
curl -X POST -F title=title -F body=body -F date=2021-10-20 http://localhost:3000/body
|
||||
|
||||
# Query Binding
|
||||
curl -X GET "http://localhost:3000/query?title=title&body=body&date=2021-10-20"
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
Validation is also possible with the binding methods. You can specify your validation rules using the `validate` struct tag.
|
||||
|
||||
Specify your struct validator in the [config](./fiber.md#structvalidator)
|
||||
Specify your struct validator in the [config](./fiber.md#structvalidator).
|
||||
|
||||
Setup your validator in the config:
|
||||
### Setup Your Validator in the Config
|
||||
|
||||
```go title="Example"
|
||||
import "github.com/go-playground/validator/v10"
|
||||
|
@ -546,18 +572,18 @@ type structValidator struct {
|
|||
validate *validator.Validate
|
||||
}
|
||||
|
||||
// Validator needs to implement the Validate method
|
||||
// Validate method implementation
|
||||
func (v *structValidator) Validate(out any) error {
|
||||
return v.validate.Struct(out)
|
||||
}
|
||||
|
||||
// Setup your validator in the config
|
||||
// Setup your validator in the Fiber config
|
||||
app := fiber.New(fiber.Config{
|
||||
StructValidator: &structValidator{validate: validator.New()},
|
||||
})
|
||||
```
|
||||
|
||||
Usage of the validation in the binding methods:
|
||||
### Usage of Validation in Binding Methods
|
||||
|
||||
```go title="Example"
|
||||
type Person struct {
|
||||
|
@ -568,7 +594,7 @@ type Person struct {
|
|||
app.Post("/", func(c fiber.Ctx) error {
|
||||
p := new(Person)
|
||||
|
||||
if err := c.Bind().JSON(p); err != nil {// <- here you receive the validation errors
|
||||
if err := c.Bind().JSON(p); err != nil { // Receives validation errors
|
||||
return err
|
||||
}
|
||||
})
|
||||
|
@ -578,13 +604,13 @@ app.Post("/", func(c fiber.Ctx) error {
|
|||
|
||||
You can set default values for fields in the struct by using the `default` struct tag. Supported types:
|
||||
|
||||
- bool
|
||||
- float variants (float32, float64)
|
||||
- int variants (int, int8, int16, int32, int64)
|
||||
- uint variants (uint, uint8, uint16, uint32, uint64)
|
||||
- string
|
||||
- a slice of the above types. As shown in the example above, **| should be used to separate between slice items**.
|
||||
- a pointer to one of the above types **(pointer to slice and slice of pointers are not supported)**.
|
||||
- `bool`
|
||||
- Float variants (`float32`, `float64`)
|
||||
- Int variants (`int`, `int8`, `int16`, `int32`, `int64`)
|
||||
- Uint variants (`uint`, `uint8`, `uint16`, `uint32`, `uint64`)
|
||||
- `string`
|
||||
- A slice of the above types. Use `|` to separate slice items.
|
||||
- A pointer to one of the above types (**pointers to slices and slices of pointers are not supported**).
|
||||
|
||||
```go title="Example"
|
||||
type Person struct {
|
||||
|
@ -600,13 +626,16 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
log.Println(p.Name) // john
|
||||
log.Println(p.Pass) // doe
|
||||
log.Println(p.Products) // ["shoe,hat"]
|
||||
log.Println(p.Name) // john
|
||||
log.Println(p.Pass) // doe
|
||||
log.Println(p.Products) // ["shoe", "hat"]
|
||||
|
||||
// ...
|
||||
})
|
||||
// Run tests with the following curl command
|
||||
|
||||
// curl "http://localhost:3000/?pass=doe"
|
||||
```
|
||||
|
||||
Run tests with the following `curl` command:
|
||||
|
||||
```bash
|
||||
curl "http://localhost:3000/?pass=doe"
|
||||
```
|
||||
|
|
|
@ -7,7 +7,7 @@ sidebar_position: 7
|
|||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
With Fiber v2.30.0, you can execute custom user functions when to run some methods. Here is a list of these hooks:
|
||||
With Fiber you can execute custom user functions at specific method execution points. Here is a list of these hooks:
|
||||
|
||||
- [OnRoute](#onroute)
|
||||
- [OnName](#onname)
|
||||
|
@ -21,7 +21,7 @@ With Fiber v2.30.0, you can execute custom user functions when to run some metho
|
|||
## Constants
|
||||
|
||||
```go
|
||||
// Handlers define a function to create hooks for Fiber.
|
||||
// Handlers define functions to create hooks for Fiber.
|
||||
type OnRouteHandler = func(Route) error
|
||||
type OnNameHandler = OnRouteHandler
|
||||
type OnGroupHandler = func(Group) error
|
||||
|
@ -34,7 +34,7 @@ type OnMountHandler = func(*App) error
|
|||
|
||||
## OnRoute
|
||||
|
||||
OnRoute is a hook to execute user functions on each route registration. Also you can get route properties by **route** parameter.
|
||||
`OnRoute` is a hook to execute user functions on each route registration. You can access route properties via the **route** parameter.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnRoute(handler ...OnRouteHandler)
|
||||
|
@ -42,10 +42,10 @@ func (h *Hooks) OnRoute(handler ...OnRouteHandler)
|
|||
|
||||
## OnName
|
||||
|
||||
OnName is a hook to execute user functions on each route naming. Also you can get route properties by **route** parameter.
|
||||
`OnName` is a hook to execute user functions on each route naming. You can access route properties via the **route** parameter.
|
||||
|
||||
:::caution
|
||||
OnName only works with naming routes, not groups.
|
||||
`OnName` only works with named routes, not groups.
|
||||
:::
|
||||
|
||||
```go title="Signature"
|
||||
|
@ -73,13 +73,11 @@ func main() {
|
|||
|
||||
app.Hooks().OnName(func(r fiber.Route) error {
|
||||
fmt.Print("Name: " + r.Name + ", ")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Hooks().OnName(func(r fiber.Route) error {
|
||||
fmt.Print("Method: " + r.Method + "\n")
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
|
@ -104,7 +102,7 @@ func main() {
|
|||
|
||||
## OnGroup
|
||||
|
||||
OnGroup is a hook to execute user functions on each group registration. Also you can get group properties by **group** parameter.
|
||||
`OnGroup` is a hook to execute user functions on each group registration. You can access group properties via the **group** parameter.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnGroup(handler ...OnGroupHandler)
|
||||
|
@ -112,10 +110,10 @@ func (h *Hooks) OnGroup(handler ...OnGroupHandler)
|
|||
|
||||
## OnGroupName
|
||||
|
||||
OnGroupName is a hook to execute user functions on each group naming. Also you can get group properties by **group** parameter.
|
||||
`OnGroupName` is a hook to execute user functions on each group naming. You can access group properties via the **group** parameter.
|
||||
|
||||
:::caution
|
||||
OnGroupName only works with naming groups, not routes.
|
||||
`OnGroupName` only works with named groups, not routes.
|
||||
:::
|
||||
|
||||
```go title="Signature"
|
||||
|
@ -124,7 +122,7 @@ func (h *Hooks) OnGroupName(handler ...OnGroupNameHandler)
|
|||
|
||||
## OnListen
|
||||
|
||||
OnListen is a hook to execute user functions on Listen, ListenTLS, Listener.
|
||||
`OnListen` is a hook to execute user functions on `Listen`, `ListenTLS`, and `Listener`.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnListen(handler ...OnListenHandler)
|
||||
|
@ -134,23 +132,35 @@ func (h *Hooks) OnListen(handler ...OnListenHandler)
|
|||
<TabItem value="onlisten-example" label="OnListen Example">
|
||||
|
||||
```go
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
package main
|
||||
|
||||
app.Hooks().OnListen(func(listenData fiber.ListenData) error {
|
||||
if fiber.IsChild() {
|
||||
return nil
|
||||
}
|
||||
scheme := "http"
|
||||
if data.TLS {
|
||||
scheme = "https"
|
||||
}
|
||||
log.Println(scheme + "://" + listenData.Host + ":" + listenData.Port)
|
||||
return nil
|
||||
})
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
app.Listen(":5000")
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := fiber.New(fiber.Config{
|
||||
DisableStartupMessage: true,
|
||||
})
|
||||
|
||||
app.Hooks().OnListen(func(listenData fiber.ListenData) error {
|
||||
if fiber.IsChild() {
|
||||
return nil
|
||||
}
|
||||
scheme := "http"
|
||||
if listenData.TLS {
|
||||
scheme = "https"
|
||||
}
|
||||
log.Println(scheme + "://" + listenData.Host + ":" + listenData.Port)
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Listen(":5000")
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
@ -158,7 +168,7 @@ app.Listen(":5000")
|
|||
|
||||
## OnFork
|
||||
|
||||
OnFork is a hook to execute user functions on Fork.
|
||||
`OnFork` is a hook to execute user functions on fork.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnFork(handler ...OnForkHandler)
|
||||
|
@ -166,7 +176,7 @@ func (h *Hooks) OnFork(handler ...OnForkHandler)
|
|||
|
||||
## OnShutdown
|
||||
|
||||
OnShutdown is a hook to execute user functions after Shutdown.
|
||||
`OnShutdown` is a hook to execute user functions after shutdown.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnShutdown(handler ...OnShutdownHandler)
|
||||
|
@ -174,10 +184,10 @@ func (h *Hooks) OnShutdown(handler ...OnShutdownHandler)
|
|||
|
||||
## OnMount
|
||||
|
||||
OnMount is a hook to execute user function after mounting process. The mount event is fired when sub-app is mounted on a parent app. The parent app is passed as a parameter. It works for app and group mounting.
|
||||
`OnMount` is a hook to execute user functions after the mounting process. The mount event is fired when a sub-app is mounted on a parent app. The parent app is passed as a parameter. It works for both app and group mounting.
|
||||
|
||||
```go title="Signature"
|
||||
func (h *Hooks) OnMount(handler ...OnMountHandler)
|
||||
func (h *Hooks) OnMount(handler ...OnMountHandler)
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
|
@ -193,24 +203,27 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
app := New()
|
||||
app := fiber.New()
|
||||
app.Get("/", testSimpleHandler).Name("x")
|
||||
|
||||
subApp := New()
|
||||
subApp := fiber.New()
|
||||
subApp.Get("/test", testSimpleHandler)
|
||||
|
||||
subApp.Hooks().OnMount(func(parent *fiber.App) error {
|
||||
fmt.Print("Mount path of parent app: "+parent.MountPath())
|
||||
// ...
|
||||
|
||||
fmt.Print("Mount path of parent app: " + parent.MountPath())
|
||||
// Additional custom logic...
|
||||
return nil
|
||||
})
|
||||
|
||||
app.Mount("/sub", subApp)
|
||||
}
|
||||
|
||||
func testSimpleHandler(c fiber.Ctx) error {
|
||||
return c.SendString("Hello, Fiber!")
|
||||
}
|
||||
|
||||
// Result:
|
||||
// Mount path of parent app:
|
||||
// Mount path of parent app: /sub
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
|
|
@ -9,7 +9,7 @@ Logs serve as an essential tool for observing program behavior, diagnosing issue
|
|||
|
||||
Fiber offers a default mechanism for logging to standard output. Additionally, it provides several global functions, including `log.Info`, `log.Errorf`, `log.Warnw`, among others, to facilitate comprehensive logging capabilities.
|
||||
|
||||
## Log levels
|
||||
## Log Levels
|
||||
|
||||
```go
|
||||
const (
|
||||
|
@ -23,9 +23,9 @@ const (
|
|||
)
|
||||
```
|
||||
|
||||
## Custom log
|
||||
## Custom Log
|
||||
|
||||
Fiber provides the `AllLogger` interface for adapting the various log libraries.
|
||||
Fiber provides the `AllLogger` interface for adapting various log libraries.
|
||||
|
||||
```go
|
||||
type CommonLogger interface {
|
||||
|
@ -41,13 +41,13 @@ type AllLogger interface {
|
|||
}
|
||||
```
|
||||
|
||||
## Print log
|
||||
## Print Log
|
||||
|
||||
Note: The Fatal level method will terminate the program after printing the log message. Please use it with caution.
|
||||
**Note:** The Fatal level method will terminate the program after printing the log message. Please use it with caution.
|
||||
|
||||
### Basic Logging
|
||||
|
||||
Logs of different levels can be directly printed. These will be entered into `messageKey`, with the default key being `msg`.
|
||||
Logs of different levels can be directly printed. These logs will be entered into `messageKey`, with the default key being `msg`.
|
||||
|
||||
```go
|
||||
log.Info("Hello, World!")
|
||||
|
@ -55,7 +55,7 @@ log.Debug("Are you OK?")
|
|||
log.Info("42 is the answer to life, the universe, and everything")
|
||||
log.Warn("We are under attack!")
|
||||
log.Error("Houston, we have a problem.")
|
||||
log.Fatal("So Long, and Thanks for All the Fislog.")
|
||||
log.Fatal("So Long, and Thanks for All the Fish.")
|
||||
log.Panic("The system is down.")
|
||||
```
|
||||
|
||||
|
@ -65,10 +65,10 @@ Logs of different levels can be formatted before printing. All such methods end
|
|||
|
||||
```go
|
||||
log.Debugf("Hello %s", "boy")
|
||||
log.Infof("%d is the answer to life, the universe, and everything", 233)
|
||||
log.Warnf("We are under attack %s!", "boss")
|
||||
log.Infof("%d is the answer to life, the universe, and everything", 42)
|
||||
log.Warnf("We are under attack, %s!", "boss")
|
||||
log.Errorf("%s, we have a problem.", "Master Shifu")
|
||||
log.Fatalf("So Long, and Thanks for All the %s.", "banana")
|
||||
log.Fatalf("So Long, and Thanks for All the %s.", "fish")
|
||||
```
|
||||
|
||||
### Key-Value Logging
|
||||
|
@ -76,14 +76,14 @@ log.Fatalf("So Long, and Thanks for All the %s.", "banana")
|
|||
Print a message with key-value pairs. If the key and value are not paired correctly, the log will output `KEYVALS UNPAIRED`.
|
||||
|
||||
```go
|
||||
log.Debugw("", "Hello", "boy")
|
||||
log.Infow("", "number", 233)
|
||||
log.Debugw("", "greeting", "Hello", "target", "boy")
|
||||
log.Infow("", "number", 42)
|
||||
log.Warnw("", "job", "boss")
|
||||
log.Errorw("", "name", "Master Shifu")
|
||||
log.Fatalw("", "fruit", "banana")
|
||||
log.Fatalw("", "fruit", "fish")
|
||||
```
|
||||
|
||||
## Global log
|
||||
## Global Log
|
||||
|
||||
For projects that require a simple, global logging function to print messages at any time, Fiber provides a global log.
|
||||
|
||||
|
@ -96,7 +96,7 @@ log.Warn("warn")
|
|||
|
||||
These global log functions allow you to log messages conveniently throughout your project.
|
||||
|
||||
The above example uses the default `log.DefaultLogger` for standard output. You can also find various pre-implemented adapters under the [contrib](https://github.com/gofiber/contrib) package such as `fiberzap` and `fiberzerolog`, or you can implement your own logger and set it as the global logger using `log.SetLogger`.This flexibility allows you to tailor the logging behavior to suit your project's needs.
|
||||
The above example uses the default `log.DefaultLogger` for standard output. You can also find various pre-implemented adapters under the [contrib](https://github.com/gofiber/contrib) package such as `fiberzap` and `fiberzerolog`, or you can implement your own logger and set it as the global logger using `log.SetLogger`. This flexibility allows you to tailor the logging behavior to suit your project's needs.
|
||||
|
||||
Here's an example using a custom logger:
|
||||
|
||||
|
@ -106,22 +106,25 @@ import (
|
|||
fiberlog "github.com/gofiber/fiber/v3/log"
|
||||
)
|
||||
|
||||
var _ log.AllLogger = (*customLogger)(nil)
|
||||
var _ fiberlog.AllLogger = (*customLogger)(nil)
|
||||
|
||||
type customLogger struct {
|
||||
stdlog *log.Logger
|
||||
}
|
||||
|
||||
// ...
|
||||
// inject your custom logger
|
||||
fiberlog.SetLogger(customLogger)
|
||||
// Implement required methods for the AllLogger interface...
|
||||
|
||||
// Inject your custom logger
|
||||
fiberlog.SetLogger(&customLogger{
|
||||
stdlog: log.New(os.Stdout, "CUSTOM ", log.LstdFlags),
|
||||
})
|
||||
```
|
||||
|
||||
## Set Level
|
||||
|
||||
`log.SetLevel` sets the minimum level of logs that will be output. The default log level is `LevelTrace`.
|
||||
|
||||
Note that this method is not **concurrent-safe**.
|
||||
**Note:** This method is not **concurrent-safe**.
|
||||
|
||||
```go
|
||||
import "github.com/gofiber/fiber/v3/log"
|
||||
|
@ -131,14 +134,14 @@ log.SetLevel(log.LevelInfo)
|
|||
|
||||
Setting the log level allows you to control the verbosity of the logs, filtering out messages below the specified level.
|
||||
|
||||
## Set output
|
||||
## Set Output
|
||||
|
||||
`log.SetOutput` sets the output destination of the logger. By default, the logger outputs logs to the console.
|
||||
|
||||
### Writing logs to stderr
|
||||
### Writing Logs to Stderr
|
||||
|
||||
```go
|
||||
var logger AllLogger = &defaultLogger{
|
||||
var logger fiberlog.AllLogger = &defaultLogger{
|
||||
stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds),
|
||||
depth: 4,
|
||||
}
|
||||
|
@ -146,31 +149,34 @@ var logger AllLogger = &defaultLogger{
|
|||
|
||||
This allows you to customize where the logs are written, such as to a file, an external logging service, or any other desired destination.
|
||||
|
||||
### Writing logs to a file
|
||||
### Writing Logs to a File
|
||||
|
||||
Set the output destination to the file, in this case `test.log`:
|
||||
Set the output destination to a file, in this case `test.log`:
|
||||
|
||||
```go
|
||||
// Output to ./test.log file
|
||||
f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return
|
||||
log.Fatal("Failed to open log file:", err)
|
||||
}
|
||||
log.SetOutput(f)
|
||||
```
|
||||
|
||||
### Writing logs to both console and file
|
||||
### Writing Logs to Both Console and File
|
||||
|
||||
The following example will write the logs to both `test.log` and `stdout`:
|
||||
|
||||
```go
|
||||
// Output to ./test.log file
|
||||
file, _ := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
file, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to open log file:", err)
|
||||
}
|
||||
iw := io.MultiWriter(os.Stdout, file)
|
||||
log.SetOutput(iw)
|
||||
```
|
||||
|
||||
## Bind context
|
||||
## Bind Context
|
||||
|
||||
To bind a logger to a specific context, use the following method. This will return a `CommonLogger` instance that is bound to the specified context.
|
||||
|
||||
|
|
|
@ -6,14 +6,13 @@ sidebar_position: 5
|
|||
toc_max_heading_level: 5
|
||||
---
|
||||
|
||||
Is used to redirect the ctx(request) to a different URL/Route.
|
||||
The redirect methods are used to redirect the context (request) to a different URL or route.
|
||||
|
||||
## Redirect Methods
|
||||
|
||||
### To
|
||||
|
||||
Redirects to the URL derived from the specified path, with specified [status](#status), a positive integer that
|
||||
corresponds to an HTTP status code.
|
||||
Redirects to the URL derived from the specified path, with a specified [status](#status), a positive integer that corresponds to an HTTP status code.
|
||||
|
||||
:::info
|
||||
If **not** specified, status defaults to **302 Found**.
|
||||
|
@ -49,10 +48,10 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
|
||||
### Route
|
||||
|
||||
Redirects to the specific route along with the parameters and queries.
|
||||
Redirects to a specific route along with the parameters and queries.
|
||||
|
||||
:::info
|
||||
If you want to send queries and params to route, you must use the [**RedirectConfig**](#redirectconfig) struct.
|
||||
If you want to send queries and params to a route, you must use the [**RedirectConfig**](#redirectconfig) struct.
|
||||
:::
|
||||
|
||||
```go title="Signature"
|
||||
|
@ -71,7 +70,7 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
|
||||
app.Get("/with-queries", func(c fiber.Ctx) error {
|
||||
// /user/fiber?data[0][name]=john&data[0][age]=10&test=doe
|
||||
return c.Route("user", RedirectConfig{
|
||||
return c.Redirect().Route("user", fiber.RedirectConfig{
|
||||
Params: fiber.Map{
|
||||
"name": "fiber",
|
||||
},
|
||||
|
@ -90,8 +89,7 @@ app.Get("/user/:name", func(c fiber.Ctx) error {
|
|||
|
||||
### Back
|
||||
|
||||
Redirects back to refer URL. It redirects to fallback URL if refer header doesn't exists, with specified status, a
|
||||
positive integer that corresponds to an HTTP status code.
|
||||
Redirects back to the referer URL. It redirects to a fallback URL if the referer header doesn't exist, with a specified status, a positive integer that corresponds to an HTTP status code.
|
||||
|
||||
:::info
|
||||
If **not** specified, status defaults to **302 Found**.
|
||||
|
@ -105,6 +103,7 @@ func (r *Redirect) Back(fallback string) error
|
|||
app.Get("/", func(c fiber.Ctx) error {
|
||||
return c.SendString("Home page")
|
||||
})
|
||||
|
||||
app.Get("/test", func(c fiber.Ctx) error {
|
||||
c.Set("Content-Type", "text/html")
|
||||
return c.SendString(`<a href="/back">Back</a>`)
|
||||
|
@ -118,7 +117,7 @@ app.Get("/back", func(c fiber.Ctx) error {
|
|||
## Controls
|
||||
|
||||
:::info
|
||||
Method are **chainable**.
|
||||
Methods are **chainable**.
|
||||
:::
|
||||
|
||||
### Status
|
||||
|
@ -126,7 +125,7 @@ Method are **chainable**.
|
|||
Sets the HTTP status code for the redirect.
|
||||
|
||||
:::info
|
||||
Is used in conjunction with [**To**](#to), [**Route**](#route) and [**Back**](#back) methods.
|
||||
It is used in conjunction with [**To**](#to), [**Route**](#route), and [**Back**](#back) methods.
|
||||
:::
|
||||
|
||||
```go title="Signature"
|
||||
|
@ -145,11 +144,11 @@ app.Get("/coffee", func(c fiber.Ctx) error {
|
|||
Sets the configuration for the redirect.
|
||||
|
||||
:::info
|
||||
Is used in conjunction with the [**Route**](#route) method.
|
||||
It is used in conjunction with the [**Route**](#route) method.
|
||||
:::
|
||||
|
||||
```go
|
||||
// RedirectConfig A config to use with Redirect().Route()
|
||||
```go title="Definition"
|
||||
// RedirectConfig is a config to use with Redirect().Route()
|
||||
type RedirectConfig struct {
|
||||
Params fiber.Map // Route parameters
|
||||
Queries map[string]string // Query map
|
||||
|
@ -158,7 +157,7 @@ type RedirectConfig struct {
|
|||
|
||||
### Flash Message
|
||||
|
||||
Similar to [Laravel](https://laravel.com/docs/11.x/redirects#redirecting-with-flashed-session-data) we can flash a message and retrieve it in the next request.
|
||||
Similar to [Laravel](https://laravel.com/docs/11.x/redirects#redirecting-with-flashed-session-data), we can flash a message and retrieve it in the next request.
|
||||
|
||||
#### Messages
|
||||
|
||||
|
@ -177,7 +176,7 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
|
||||
#### Message
|
||||
|
||||
Get flash message by key. Check [With](#with) for more information.
|
||||
Get a flash message by key. Check [With](#with) for more information.
|
||||
|
||||
```go title="Signature"
|
||||
func (r *Redirect) Message(key string) *Redirect
|
||||
|
@ -241,10 +240,9 @@ app.Get("/", func(c fiber.Ctx) error {
|
|||
|
||||
#### WithInput
|
||||
|
||||
You can send input data by using `WithInput()`.
|
||||
They will be sent as a cookie.
|
||||
You can send input data by using `WithInput()`. They will be sent as a cookie.
|
||||
|
||||
This method can send form, multipart form, query data to redirected route depending on the request content type.
|
||||
This method can send form, multipart form, or query data to the redirected route depending on the request content type.
|
||||
|
||||
```go title="Signature"
|
||||
func (r *Redirect) WithInput() *Redirect
|
||||
|
|
Loading…
Reference in New Issue