mirror of https://github.com/gofiber/fiber.git
Updates to documentation
parent
2c7bdb9fd1
commit
a29edcff99
|
@ -39,7 +39,7 @@ Fiber v3 is currently in beta and under active development. While it offers exci
|
||||||
|
|
||||||
## ⚙️ Installation
|
## ⚙️ 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
|
```bash
|
||||||
go mod init github.com/your/repo
|
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.
|
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
|
package main
|
||||||
|
|
||||||
import (
|
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)
|
### 📖 [**Basic Routing**](https://docs.gofiber.io/#basic-routing)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
@ -169,23 +178,33 @@ func main() {
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 📖 [**Route Naming**](https://docs.gofiber.io/api/app#name)
|
#### 📖 [**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() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
// GET /api/register
|
|
||||||
app.Get("/api/*", func(c fiber.Ctx) error {
|
app.Get("/api/*", func(c fiber.Ctx) error {
|
||||||
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
msg := fmt.Sprintf("✋ %s", c.Params("*"))
|
||||||
return c.SendString(msg) // => ✋ register
|
return c.SendString(msg) // => ✋ register
|
||||||
}).Name("api")
|
}).Name("api")
|
||||||
|
|
||||||
data, _ := json.MarshalIndent(app.GetRoute("api"), "", " ")
|
route := app.GetRoute("api")
|
||||||
fmt.Print(string(data))
|
|
||||||
|
data, _ := json.MarshalIndent(route, "", " ")
|
||||||
|
fmt.Println(string(data))
|
||||||
// Prints:
|
// Prints:
|
||||||
// {
|
// {
|
||||||
// "method": "GET",
|
// "method": "GET",
|
||||||
|
@ -198,15 +217,24 @@ func main() {
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 📖 [**Serving Static Files**](https://docs.gofiber.io/api/app#static)
|
#### 📖 [**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() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
// Serve static files from the "./public" directory
|
||||||
app.Get("/*", static.New("./public"))
|
app.Get("/*", static.New("./public"))
|
||||||
// => http://localhost:3000/js/script.js
|
// => http://localhost:3000/js/script.js
|
||||||
// => http://localhost:3000/css/style.css
|
// => http://localhost:3000/css/style.css
|
||||||
|
@ -215,27 +243,36 @@ func main() {
|
||||||
// => http://localhost:3000/prefix/js/script.js
|
// => http://localhost:3000/prefix/js/script.js
|
||||||
// => http://localhost:3000/prefix/css/style.css
|
// => http://localhost:3000/prefix/css/style.css
|
||||||
|
|
||||||
|
// Serve a single file for any unmatched routes
|
||||||
app.Get("*", static.New("./public/index.html"))
|
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"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 📖 [**Middleware & Next**](https://docs.gofiber.io/api/ctx#next)
|
#### 📖 [**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() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
// Match any route
|
// Middleware that matches any route
|
||||||
app.Use(func(c fiber.Ctx) error {
|
app.Use(func(c fiber.Ctx) error {
|
||||||
fmt.Println("🥇 First handler")
|
fmt.Println("🥇 First handler")
|
||||||
return c.Next()
|
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 {
|
app.Use("/api", func(c fiber.Ctx) error {
|
||||||
fmt.Println("🥈 Second handler")
|
fmt.Println("🥈 Second handler")
|
||||||
return c.Next()
|
return c.Next()
|
||||||
|
@ -249,13 +286,12 @@ func main() {
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>📚 Show more code examples</summary>
|
<summary>📚 Show more code examples</summary>
|
||||||
|
|
||||||
### Views engines
|
### Views Engines
|
||||||
|
|
||||||
📖 [Config](https://docs.gofiber.io/api/fiber#config)
|
📖 [Config](https://docs.gofiber.io/api/fiber#config)
|
||||||
📖 [Engines](https://github.com/gofiber/template)
|
📖 [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.
|
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 title="Example"
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -278,12 +312,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// You can setup Views engine before initiation app:
|
// Initialize a new Fiber app with Pug template engine
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
Views: pug.New("./views", ".pug"),
|
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 {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
return c.Render("home", fiber.Map{
|
return c.Render("home", fiber.Map{
|
||||||
"title": "Homepage",
|
"title": "Homepage",
|
||||||
|
@ -295,24 +329,32 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Grouping routes into chains
|
### Grouping Routes into Chains
|
||||||
|
|
||||||
📖 [Group](https://docs.gofiber.io/api/app#group)
|
📖 [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 {
|
func middleware(c fiber.Ctx) error {
|
||||||
fmt.Println("Don't mind me!")
|
log.Println("Middleware executed")
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func handler(c fiber.Ctx) error {
|
func handler(c fiber.Ctx) error {
|
||||||
return c.SendString(c.Path())
|
return c.SendString("Handler response")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
// Root API route
|
// Root API group with middleware
|
||||||
api := app.Group("/api", middleware) // /api
|
api := app.Group("/api", middleware) // /api
|
||||||
|
|
||||||
// API v1 routes
|
// API v1 routes
|
||||||
|
@ -325,16 +367,15 @@ func main() {
|
||||||
v2.Get("/list", handler) // /api/v2/list
|
v2.Get("/list", handler) // /api/v2/list
|
||||||
v2.Get("/user", handler) // /api/v2/user
|
v2.Get("/user", handler) // /api/v2/user
|
||||||
|
|
||||||
// ...
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Middleware logger
|
### Middleware Logger
|
||||||
|
|
||||||
📖 [Logger](https://docs.gofiber.io/api/middleware/logger)
|
📖 [Logger](https://docs.gofiber.io/api/middleware/logger)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -347,9 +388,13 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
// Use Logger middleware
|
||||||
app.Use(logger.New())
|
app.Use(logger.New())
|
||||||
|
|
||||||
// ...
|
// Define routes
|
||||||
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
return c.SendString("Hello, Logger!")
|
||||||
|
})
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
|
@ -359,7 +404,9 @@ func main() {
|
||||||
|
|
||||||
📖 [CORS](https://docs.gofiber.io/api/middleware/cors)
|
📖 [CORS](https://docs.gofiber.io/api/middleware/cors)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -370,9 +417,13 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
// Use CORS middleware with default settings
|
||||||
app.Use(cors.New())
|
app.Use(cors.New())
|
||||||
|
|
||||||
// ...
|
// Define routes
|
||||||
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
return c.SendString("CORS enabled!")
|
||||||
|
})
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
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
|
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)
|
📖 [HTTP Methods](https://docs.gofiber.io/api/ctx#status)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
// Define routes
|
||||||
app.Get("/", static.New("./public"))
|
app.Get("/", static.New("./public"))
|
||||||
|
|
||||||
app.Get("/demo", func(c fiber.Ctx) error {
|
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 {
|
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 {
|
app.Use(func(c fiber.Ctx) error {
|
||||||
return c.SendStatus(404)
|
return c.SendStatus(fiber.StatusNotFound) // => 404 "Not Found"
|
||||||
// => 404 "Not Found"
|
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
|
@ -416,7 +475,15 @@ func main() {
|
||||||
|
|
||||||
📖 [JSON](https://docs.gofiber.io/api/ctx#json)
|
📖 [JSON](https://docs.gofiber.io/api/ctx#json)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Age int `json:"age"`
|
Age int `json:"age"`
|
||||||
|
@ -425,11 +492,13 @@ type User struct {
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
// Route that returns a JSON object
|
||||||
app.Get("/user", func(c fiber.Ctx) error {
|
app.Get("/user", func(c fiber.Ctx) error {
|
||||||
return c.JSON(&User{"John", 20})
|
return c.JSON(&User{"John", 20})
|
||||||
// => {"name":"John", "age":20}
|
// => {"name":"John", "age":20}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Route that returns a JSON map
|
||||||
app.Get("/json", func(c fiber.Ctx) error {
|
app.Get("/json", func(c fiber.Ctx) error {
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(fiber.Map{
|
||||||
"success": true,
|
"success": true,
|
||||||
|
@ -446,7 +515,9 @@ func main() {
|
||||||
|
|
||||||
📖 [Websocket](https://github.com/gofiber/websocket)
|
📖 [Websocket](https://github.com/gofiber/websocket)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -455,26 +526,31 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
// WebSocket route
|
||||||
for {
|
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
|
||||||
mt, msg, err := c.ReadMessage()
|
defer c.Close()
|
||||||
if err != nil {
|
for {
|
||||||
log.Println("read:", err)
|
// Read message from client
|
||||||
break
|
mt, msg, err := c.ReadMessage()
|
||||||
}
|
if err != nil {
|
||||||
log.Printf("recv: %s", msg)
|
log.Println("read:", err)
|
||||||
err = c.WriteMessage(mt, msg)
|
break
|
||||||
if err != nil {
|
}
|
||||||
log.Println("write:", err)
|
log.Printf("recv: %s", msg)
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
// Write message back to client
|
||||||
// ws://localhost:3000/ws
|
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)
|
📖 [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 (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
"github.com/valyala/fasthttp"
|
"github.com/valyala/fasthttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
app.Get("/sse", func(c fiber.Ctx) error {
|
// Server-Sent Events route
|
||||||
c.Set("Content-Type", "text/event-stream")
|
app.Get("/sse", func(c fiber.Ctx) error {
|
||||||
c.Set("Cache-Control", "no-cache")
|
c.Set("Content-Type", "text/event-stream")
|
||||||
c.Set("Connection", "keep-alive")
|
c.Set("Cache-Control", "no-cache")
|
||||||
c.Set("Transfer-Encoding", "chunked")
|
c.Set("Connection", "keep-alive")
|
||||||
|
c.Set("Transfer-Encoding", "chunked")
|
||||||
|
|
||||||
c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) {
|
c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
|
||||||
fmt.Println("WRITER")
|
var i int
|
||||||
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 {
|
w.Flush()
|
||||||
i++
|
time.Sleep(5 * time.Second)
|
||||||
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()
|
return nil
|
||||||
time.Sleep(5 * time.Second)
|
})
|
||||||
}
|
|
||||||
}))
|
|
||||||
|
|
||||||
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)
|
📖 [Recover](https://docs.gofiber.io/api/middleware/recover)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -536,8 +618,10 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
|
// Use Recover middleware to handle panics gracefully
|
||||||
app.Use(recover.New())
|
app.Use(recover.New())
|
||||||
|
|
||||||
|
// Route that intentionally panics
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
panic("normally this would crash your app")
|
panic("normally this would crash your app")
|
||||||
})
|
})
|
||||||
|
@ -546,13 +630,13 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Using Trusted Proxy
|
### Using Trusted Proxy
|
||||||
|
|
||||||
📖 [Config](https://docs.gofiber.io/api/fiber#config)
|
📖 [Config](https://docs.gofiber.io/api/fiber#config)
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
@ -561,6 +645,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
|
// Trust all proxies (use with caution)
|
||||||
TrustProxy: true,
|
TrustProxy: true,
|
||||||
TrustProxyConfig: fiber.TrustProxyConfig{
|
TrustProxyConfig: fiber.TrustProxyConfig{
|
||||||
Proxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
|
Proxies: []string{"0.0.0.0", "1.1.1.1/30"}, // IP address or IP address range
|
||||||
|
@ -568,6 +653,11 @@ func main() {
|
||||||
ProxyHeader: fiber.HeaderXForwardedFor,
|
ProxyHeader: fiber.HeaderXForwardedFor,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Define routes
|
||||||
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
return c.SendString("Trusted Proxy Configured!")
|
||||||
|
})
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -583,14 +673,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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [helmet](https://github.com/gofiber/fiber/tree/main/middleware/helmet) | Helps secure your apps by setting various HTTP headers. |
|
||||||
|
@ -606,22 +696,22 @@ 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. |
|
| [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. |
|
| [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. |
|
| [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. |
|
| [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
|
## 🧬 External Middleware
|
||||||
|
|
||||||
List of externally hosted middleware modules and maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
List of externally hosted middleware modules and maintained by the [Fiber team](https://github.com/orgs/gofiber/people).
|
||||||
|
|
||||||
| Middleware | Description |
|
| Middleware | Description |
|
||||||
| :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------- |
|
|-------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|
|
||||||
| [contrib](https://github.com/gofiber/contrib) | Third party middlewares |
|
| [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. |
|
| [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. |
|
| [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
|
## 🕶️ 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
|
## 👍 Contribute
|
||||||
|
|
||||||
|
@ -629,12 +719,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.
|
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).
|
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).
|
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 help**: Display available commands.
|
||||||
- **make audit**: Conduct quality checks.
|
- **make audit**: Conduct quality checks.
|
||||||
|
@ -649,22 +739,22 @@ Run these commands to ensure your code adheres to project standards and best pra
|
||||||
|
|
||||||
## ☕ Supporters
|
## ☕ 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 |
|
| | User | Donation |
|
||||||
| :--------------------------------------------------------- | :----------------------------------------------- | :------- |
|
| ---------------------------------------------------------- | ------------------------------------------------ | -------- |
|
||||||
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
|  | [@destari](https://github.com/destari) | ☕ x 10 |
|
||||||
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
|  | [@dembygenesis](https://github.com/dembygenesis) | ☕ x 5 |
|
||||||
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
|  | [@thomasvvugt](https://github.com/thomasvvugt) | ☕ x 5 |
|
||||||
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
|  | [@hendratommy](https://github.com/hendratommy) | ☕ x 5 |
|
||||||
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
|  | [@ekaputra07](https://github.com/ekaputra07) | ☕ x 5 |
|
||||||
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
|  | [@jorgefuertes](https://github.com/jorgefuertes) | ☕ x 5 |
|
||||||
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
|  | [@candidosales](https://github.com/candidosales) | ☕ x 5 |
|
||||||
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
|  | [@l0nax](https://github.com/l0nax) | ☕ x 3 |
|
||||||
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
|  | [@bihe](https://github.com/bihe) | ☕ x 3 |
|
||||||
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
|  | [@justdave](https://github.com/justdave) | ☕ x 3 |
|
||||||
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
|  | [@koddr](https://github.com/koddr) | ☕ x 1 |
|
||||||
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
|  | [@lapolinar](https://github.com/lapolinar) | ☕ x 1 |
|
||||||
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
|  | [@diegowifi](https://github.com/diegowifi) | ☕ x 1 |
|
||||||
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
|  | [@ssimk0](https://github.com/ssimk0) | ☕ x 1 |
|
||||||
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
|  | [@raymayemir](https://github.com/raymayemir) | ☕ x 1 |
|
||||||
|
|
487
docs/api/app.md
487
docs/api/app.md
|
@ -17,18 +17,28 @@ import RoutingHandler from './../partials/routing/handler.md';
|
||||||
|
|
||||||
### Mounting
|
### 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() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
micro := fiber.New()
|
micro := fiber.New()
|
||||||
|
|
||||||
|
// Mount the micro app on the "/john" route
|
||||||
app.Use("/john", micro) // GET /john/doe -> 200 OK
|
app.Use("/john", micro) // GET /john/doe -> 200 OK
|
||||||
|
|
||||||
micro.Get("/doe", func(c fiber.Ctx) error {
|
micro.Get("/doe", func(c fiber.Ctx) error {
|
||||||
return c.SendStatus(fiber.StatusOK)
|
return c.SendStatus(fiber.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Fatal(app.Listen(":3000"))
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -40,8 +50,16 @@ The `MountPath` property contains one or more path patterns on which a sub-app w
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) MountPath() string
|
func (app *App) MountPath() string
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
```go title="Examples"
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
one := fiber.New()
|
one := fiber.New()
|
||||||
|
@ -51,16 +69,17 @@ func main() {
|
||||||
two.Use("/three", three)
|
two.Use("/three", three)
|
||||||
one.Use("/two", two)
|
one.Use("/two", two)
|
||||||
app.Use("/one", one)
|
app.Use("/one", one)
|
||||||
|
|
||||||
one.MountPath() // "/one"
|
fmt.Println("Mount paths:")
|
||||||
two.MountPath() // "/one/two"
|
fmt.Println("one.MountPath():", one.MountPath()) // "/one"
|
||||||
three.MountPath() // "/one/two/three"
|
fmt.Println("two.MountPath():", two.MountPath()) // "/one/two"
|
||||||
app.MountPath() // ""
|
fmt.Println("three.MountPath():", three.MountPath()) // "/one/two/three"
|
||||||
|
fmt.Println("app.MountPath():", app.MountPath()) // ""
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
:::caution
|
:::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
|
### Group
|
||||||
|
@ -70,22 +89,34 @@ You can group routes by creating a `*Group` struct.
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) Group(prefix string, handlers ...Handler) Router
|
func (app *App) Group(prefix string, handlers ...Handler) Router
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
```go title="Examples"
|
|
||||||
func main() {
|
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 := api.Group("/v1", handler) // /api/v1
|
||||||
v1.Get("/list", handler) // /api/v1/list
|
v1.Get("/list", handler) // /api/v1/list
|
||||||
v1.Get("/user", handler) // /api/v1/user
|
v1.Get("/user", handler) // /api/v1/user
|
||||||
|
|
||||||
v2 := api.Group("/v2", handler) // /api/v2
|
v2 := api.Group("/v2", handler) // /api/v2
|
||||||
v2.Get("/list", handler) // /api/v2/list
|
v2.Get("/list", handler) // /api/v2/list
|
||||||
v2.Get("/user", handler) // /api/v2/user
|
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
|
```go
|
||||||
type Register interface {
|
type Register interface {
|
||||||
All(handler Handler, middleware ...Handler) Register
|
All(handler Handler, middleware ...Handler) Register
|
||||||
Get(handler Handler, middleware ...Handler) Register
|
Get(handler Handler, middleware ...Handler) Register
|
||||||
Head(handler Handler, middleware ...Handler) Register
|
Head(handler Handler, middleware ...Handler) Register
|
||||||
Post(handler Handler, middleware ...Handler) Register
|
Post(handler Handler, middleware ...Handler) Register
|
||||||
Put(handler Handler, middleware ...Handler) Register
|
Put(handler Handler, middleware ...Handler) Register
|
||||||
Delete(handler Handler, middleware ...Handler) Register
|
Delete(handler Handler, middleware ...Handler) Register
|
||||||
Connect(handler Handler, middleware ...Handler) Register
|
Connect(handler Handler, middleware ...Handler) Register
|
||||||
Options(handler Handler, middleware ...Handler) Register
|
Options(handler Handler, middleware ...Handler) Register
|
||||||
Trace(handler Handler, middleware ...Handler) Register
|
Trace(handler Handler, middleware ...Handler) Register
|
||||||
Patch(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>
|
</details>
|
||||||
|
|
||||||
```go title="Examples"
|
```go title="Example"
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
// use `Route` as chainable route declaration method
|
// Use `Route` as a chainable route declaration method
|
||||||
app.Route("/test").Get(func(c fiber.Ctx) error {
|
app.Route("/test").Get(func(c fiber.Ctx) error {
|
||||||
return c.SendString("GET /test")
|
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")
|
|
||||||
})
|
|
||||||
|
|
||||||
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
|
### HandlersCount
|
||||||
|
|
||||||
This method returns the amount of registered handlers.
|
This method returns the number of registered handlers.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) HandlersCount() uint32
|
func (app *App) HandlersCount() uint32
|
||||||
|
@ -169,14 +209,21 @@ func (app *App) HandlersCount() uint32
|
||||||
|
|
||||||
### Stack
|
### Stack
|
||||||
|
|
||||||
This method returns the original router stack
|
This method returns the original router stack.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) Stack() [][]*Route
|
func (app *App) Stack() [][]*Route
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Examples"
|
```go title="Example"
|
||||||
var handler = func(c fiber.Ctx) error { return nil }
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
@ -184,10 +231,10 @@ func main() {
|
||||||
app.Get("/john/:age", handler)
|
app.Get("/john/:age", handler)
|
||||||
app.Post("/register", handler)
|
app.Post("/register", handler)
|
||||||
|
|
||||||
data, _ := json.MarshalIndent(app.Stack(), "", " ")
|
data, _err_ := json.MarshalIndent(app.Stack(), "", " ")
|
||||||
fmt.Println(string(data))
|
fmt.Println(string(data))
|
||||||
|
|
||||||
app.Listen(":3000")
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -228,25 +275,32 @@ func main() {
|
||||||
|
|
||||||
### Name
|
### Name
|
||||||
|
|
||||||
This method assigns the name of latest created route.
|
This method assigns the name to the latest created route.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) Name(name string) Router
|
func (app *App) Name(name string) Router
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Examples"
|
```go title="Example"
|
||||||
var handler = func(c fiber.Ctx) error { return nil }
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var handler = func(c fiber.Ctx) error { return nil }
|
||||||
|
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
app.Get("/", handler)
|
app.Get("/", handler)
|
||||||
app.Name("index")
|
app.Name("index")
|
||||||
|
|
||||||
app.Get("/doe", handler).Name("home")
|
app.Get("/doe", handler).Name("home")
|
||||||
|
|
||||||
app.Trace("/tracer", handler).Name("tracert")
|
app.Trace("/tracer", handler).Name("tracert")
|
||||||
|
|
||||||
app.Delete("/delete", handler).Name("delete")
|
app.Delete("/delete", handler).Name("delete")
|
||||||
|
|
||||||
a := app.Group("/a")
|
a := app.Group("/a")
|
||||||
|
@ -255,10 +309,9 @@ func main() {
|
||||||
a.Get("/test", handler).Name("test")
|
a.Get("/test", handler).Name("test")
|
||||||
|
|
||||||
data, _ := json.MarshalIndent(app.Stack(), "", " ")
|
data, _ := json.MarshalIndent(app.Stack(), "", " ")
|
||||||
fmt.Print(string(data))
|
fmt.Println(string(data))
|
||||||
|
|
||||||
app.Listen(":3000")
|
|
||||||
|
|
||||||
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -335,25 +388,34 @@ func main() {
|
||||||
|
|
||||||
### GetRoute
|
### GetRoute
|
||||||
|
|
||||||
This method gets the route by name.
|
This method retrieves a route by its name.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) GetRoute(name string) Route
|
func (app *App) GetRoute(name string) Route
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Examples"
|
```go title="Example"
|
||||||
var handler = func(c fiber.Ctx) error { return nil }
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
app.Get("/", handler).Name("index")
|
app.Get("/", handler).Name("index")
|
||||||
|
|
||||||
data, _ := json.MarshalIndent(app.GetRoute("index"), "", " ")
|
route := app.GetRoute("index")
|
||||||
fmt.Print(string(data))
|
|
||||||
|
|
||||||
|
data, _ := json.MarshalIndent(route, "", " ")
|
||||||
|
fmt.Println(string(data))
|
||||||
|
|
||||||
app.Listen(":3000")
|
log.Fatal(app.Listen(":3000"))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -373,22 +435,38 @@ func main() {
|
||||||
|
|
||||||
### GetRoutes
|
### GetRoutes
|
||||||
|
|
||||||
This method gets all routes.
|
This method retrieves all routes.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) GetRoutes(filterUseOption ...bool) []Route
|
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() {
|
func main() {
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
app.Post("/", func (c fiber.Ctx) error {
|
|
||||||
|
app.Post("/", func(c fiber.Ctx) error {
|
||||||
return c.SendString("Hello, World!")
|
return c.SendString("Hello, World!")
|
||||||
}).Name("index")
|
}).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 +488,7 @@ func main() {
|
||||||
|
|
||||||
## Config
|
## 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"
|
```go title="Signature"
|
||||||
func (app *App) Config() Config
|
func (app *App) Config() Config
|
||||||
|
@ -418,7 +496,7 @@ func (app *App) Config() Config
|
||||||
|
|
||||||
## Handler
|
## 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"
|
```go title="Signature"
|
||||||
func (app *App) Handler() fasthttp.RequestHandler
|
func (app *App) Handler() fasthttp.RequestHandler
|
||||||
|
@ -426,7 +504,7 @@ func (app *App) Handler() fasthttp.RequestHandler
|
||||||
|
|
||||||
## ErrorHandler
|
## 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"
|
```go title="Signature"
|
||||||
func (app *App) ErrorHandler(ctx Ctx, err error) error
|
func (app *App) ErrorHandler(ctx Ctx, err error) error
|
||||||
|
@ -434,15 +512,23 @@ func (app *App) ErrorHandler(ctx Ctx, err error) error
|
||||||
|
|
||||||
## NewCtxFunc
|
## NewCtxFunc
|
||||||
|
|
||||||
NewCtxFunc allows to customize the ctx struct as we want.
|
`NewCtxFunc` allows you to customize the `ctx` struct as needed.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) NewCtxFunc(function func(app *App) CustomCtx)
|
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 {
|
type CustomCtx struct {
|
||||||
DefaultCtx
|
fiber.DefaultCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom method
|
// Custom method
|
||||||
|
@ -450,125 +536,156 @@ func (c *CustomCtx) Params(key string, defaultValue ...string) string {
|
||||||
return "prefix_" + c.DefaultCtx.Params(key)
|
return "prefix_" + c.DefaultCtx.Params(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
app := New()
|
func main() {
|
||||||
app.NewCtxFunc(func(app *fiber.App) fiber.CustomCtx {
|
app := fiber.New()
|
||||||
return &CustomCtx{
|
|
||||||
DefaultCtx: *NewDefaultCtx(app),
|
app.NewCtxFunc(func(app *fiber.App) fiber.CustomCtx {
|
||||||
}
|
return &CustomCtx{
|
||||||
})
|
DefaultCtx: *fiber.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"))
|
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
|
## RegisterCustomBinder
|
||||||
|
|
||||||
You can register custom binders to use as [`Bind().Custom("name")`](bind.md#custom).
|
You can register custom binders to use with [`Bind().Custom("name")`](bind.md#custom). They should be compatible with the `CustomBinder` interface.
|
||||||
They should be compatible with CustomBinder interface.
|
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) RegisterCustomBinder(binder CustomBinder)
|
func (app *App) RegisterCustomBinder(binder CustomBinder)
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Examples"
|
```go title="Example"
|
||||||
app := fiber.New()
|
package main
|
||||||
|
|
||||||
// My custom binder
|
import (
|
||||||
customBinder := &customBinder{}
|
"log"
|
||||||
// Name of custom binder, which will be used as Bind().Custom("name")
|
|
||||||
func (*customBinder) Name() string {
|
"github.com/gofiber/fiber/v3"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type customBinder struct{}
|
||||||
|
|
||||||
|
func (cb *customBinder) Name() string {
|
||||||
return "custom"
|
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"}
|
return []string{"application/yaml"}
|
||||||
}
|
}
|
||||||
// Parse the body and bind it to the out interface
|
|
||||||
func (*customBinder) Parse(c Ctx, out any) error {
|
func (cb *customBinder) Parse(c fiber.Ctx, out any) error {
|
||||||
// parse yaml body
|
// Parse YAML body
|
||||||
return yaml.Unmarshal(c.Body(), out)
|
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"
|
func main() {
|
||||||
app.Post("/custom", func(c Ctx) error {
|
app := fiber.New()
|
||||||
var user User
|
|
||||||
// output: {Name:John}
|
// Register custom binder
|
||||||
// Custom binder is used by the name
|
app.RegisterCustomBinder(&customBinder{})
|
||||||
if err := c.Bind().Custom("custom", &user); err != nil {
|
|
||||||
return err
|
app.Post("/custom", func(c fiber.Ctx) error {
|
||||||
}
|
var user User
|
||||||
// ...
|
// Use Custom binder by name
|
||||||
return c.JSON(user)
|
if err := c.Bind().Custom("custom", &user); err != nil {
|
||||||
})
|
return err
|
||||||
// curl -X POST http://localhost:3000/normal -H "Content-Type: application/yaml" -d "name: Doe"
|
}
|
||||||
app.Post("/normal", func(c Ctx) error {
|
return c.JSON(user)
|
||||||
var user User
|
})
|
||||||
// output: {Name:Doe}
|
|
||||||
// Custom binder is used by the mime type
|
app.Post("/normal", func(c fiber.Ctx) error {
|
||||||
if err := c.Bind().Body(&user); err != nil {
|
var user User
|
||||||
return err
|
// Custom binder is used by the MIME type
|
||||||
}
|
if err := c.Bind().Body(&user); err != nil {
|
||||||
// ...
|
return err
|
||||||
return c.JSON(user)
|
}
|
||||||
})
|
return c.JSON(user)
|
||||||
|
})
|
||||||
|
|
||||||
|
log.Fatal(app.Listen(":3000"))
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## RegisterCustomConstraint
|
## RegisterCustomConstraint
|
||||||
|
|
||||||
RegisterCustomConstraint allows to register custom constraint.
|
`RegisterCustomConstraint` allows you to register custom constraints.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) RegisterCustomConstraint(constraint CustomConstraint)
|
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
|
## 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"
|
```go title="Signature"
|
||||||
func (app *App) SetTLSHandler(tlsHandler *TLSHandler)
|
func (app *App) SetTLSHandler(tlsHandler *TLSHandler)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test
|
## 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"
|
```go title="Signature"
|
||||||
func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error)
|
func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error)
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Examples"
|
```go title="Example"
|
||||||
// Create route with GET method for test:
|
package main
|
||||||
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!")
|
import (
|
||||||
})
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
|
||||||
// http.Request
|
"github.com/gofiber/fiber/v3"
|
||||||
req := httptest.NewRequest("GET", "http://google.com", nil)
|
)
|
||||||
req.Header.Set("X-Custom-Header", "hi")
|
|
||||||
|
|
||||||
// http.Response
|
func main() {
|
||||||
resp, _ := app.Test(req)
|
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:
|
// Create http.Request
|
||||||
if resp.StatusCode == fiber.StatusOK {
|
req := httptest.NewRequest("GET", "http://google.com", nil)
|
||||||
body, _ := io.ReadAll(resp.Body)
|
req.Header.Set("X-Custom-Header", "hi")
|
||||||
fmt.Println(string(body)) // => Hello, World!
|
|
||||||
|
// 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
|
||||||
|
|
||||||
Hooks is a method to return [hooks](./hooks.md) property.
|
`Hooks` is a method to return the [hooks](./hooks.md) property.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (app *App) Hooks() *Hooks
|
func (app *App) Hooks() *Hooks
|
||||||
|
@ -576,7 +693,7 @@ func (app *App) Hooks() *Hooks
|
||||||
|
|
||||||
## RebuildTree
|
## 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"
|
```go title="Signature"
|
||||||
func (app *App) RebuildTree() *App
|
func (app *App) RebuildTree() *App
|
||||||
|
@ -588,16 +705,32 @@ func (app *App) RebuildTree() *App
|
||||||
|
|
||||||
Here’s an example of how to define and register routes dynamically:
|
Here’s an example of how to define and register routes dynamically:
|
||||||
|
|
||||||
```go
|
```go title="Example"
|
||||||
app.Get("/define", func(c Ctx) error { // Define a new route dynamically
|
package main
|
||||||
app.Get("/dynamically-defined", func(c Ctx) error { // Adding a dynamically defined route
|
|
||||||
return c.SendStatus(http.StatusOK)
|
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
|
log.Fatal(app.Listen(":3000"))
|
||||||
|
}
|
||||||
return c.SendStatus(http.StatusOK)
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
||||||
|
|
367
docs/api/bind.md
367
docs/api/bind.md
|
@ -6,13 +6,11 @@ sidebar_position: 4
|
||||||
toc_max_heading_level: 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
|
:::info
|
||||||
|
All binder returned values are only valid within the handler. Do not store any references.
|
||||||
All binder returned value 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)
|
Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more...](../#zero-allocation)
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Binders
|
## Binders
|
||||||
|
@ -32,22 +30,21 @@ Make copies or use the [**`Immutable`**](./ctx.md) setting instead. [Read more..
|
||||||
|
|
||||||
Binds the request body to a struct.
|
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 |
|
| `application/x-www-form-urlencoded` | `form` |
|
||||||
| `multipart/form-data` | form |
|
| `multipart/form-data` | `form` |
|
||||||
| `application/json` | json |
|
| `application/json` | `json` |
|
||||||
| `application/xml` | xml |
|
| `application/xml` | `xml` |
|
||||||
| `text/xml` | xml |
|
| `text/xml` | `xml` |
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (b *Bind) Body(out any) error
|
func (b *Bind) Body(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `json:"name" xml:"name" form:"name"`
|
Name string `json:"name" xml:"name" form:"name"`
|
||||||
Pass string `json:"pass" xml:"pass" form:"pass"`
|
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.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) Form(out any) error
|
func (b *Bind) Form(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `form:"name"`
|
Name string `form:"name"`
|
||||||
Pass string `form:"pass"`
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) JSON(out any) error
|
func (b *Bind) JSON(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Pass string `json:"pass"`
|
Pass string `json:"pass"`
|
||||||
|
@ -145,25 +144,25 @@ 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.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) MultipartForm(out any) error
|
func (b *Bind) MultipartForm(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `form:"name"`
|
Name string `form:"name"`
|
||||||
Pass string `form:"pass"`
|
Pass string `form:"pass"`
|
||||||
|
@ -181,25 +180,25 @@ 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"
|
```go title="Signature"
|
||||||
func (b *Bind) XML(out any) error
|
func (b *Bind) XML(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `xml:"name"`
|
Name string `xml:"name"`
|
||||||
Pass string `xml:"pass"`
|
Pass string `xml:"pass"`
|
||||||
|
@ -217,27 +216,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
|
### Cookie
|
||||||
|
|
||||||
This method is similar to [Body-Binding](#body), but for cookie parameters.
|
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"`.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) Cookie(out any) error
|
func (b *Bind) Cookie(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `cookie:"name"`
|
Name string `cookie:"name"`
|
||||||
Age int `cookie:"age"`
|
Age int `cookie:"age"`
|
||||||
Job bool `cookie:"job"`
|
Job bool `cookie:"job"`
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
@ -247,29 +247,32 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(p.Name) // Joseph
|
log.Println(p.Name) // Joseph
|
||||||
log.Println(p.Age) // 23
|
log.Println(p.Age) // 23
|
||||||
log.Println(p.Job) // true
|
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
|
### Header
|
||||||
|
|
||||||
This method is similar to [Body-Binding](#body), but for request headers.
|
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"`.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) Header(out any) error
|
func (b *Bind) Header(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `header:"name"`
|
Name string `header:"name"`
|
||||||
Pass string `header:"pass"`
|
Pass string `header:"pass"`
|
||||||
Products []string `header:"products"`
|
Products []string `header:"products"`
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
@ -281,30 +284,32 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
log.Println(p.Name) // john
|
log.Println(p.Name) // john
|
||||||
log.Println(p.Pass) // doe
|
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
|
### Query
|
||||||
|
|
||||||
This method is similar to [Body-Binding](#body), but for query parameters.
|
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"`.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) Query(out any) error
|
func (b *Bind) Query(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `query:"name"`
|
Name string `query:"name"`
|
||||||
Pass string `query:"pass"`
|
Pass string `query:"pass"`
|
||||||
Products []string `query:"products"`
|
Products []string `query:"products"`
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
@ -314,40 +319,41 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(p.Name) // john
|
log.Println(p.Name) // john
|
||||||
log.Println(p.Pass) // doe
|
log.Println(p.Pass) // doe
|
||||||
// fiber.Config{EnableSplittingOnParsers: false} - default
|
// Depending on fiber.Config{EnableSplittingOnParsers: false} - default
|
||||||
log.Println(p.Products) // ["shoe,hat"]
|
log.Println(p.Products) // ["shoe,hat"]
|
||||||
// fiber.Config{EnableSplittingOnParsers: true}
|
// With fiber.Config{EnableSplittingOnParsers: true}
|
||||||
// log.Println(p.Products) // ["shoe", "hat"]
|
// 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
|
:::info
|
||||||
For more parser settings please look here [Config](fiber.md#enablesplittingonparsers)
|
For more parser settings, please refer to [Config](fiber.md#enablesplittingonparsers)
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### RespHeader
|
### RespHeader
|
||||||
|
|
||||||
This method is similar to [Body-Binding](#body), but for response headers.
|
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"`.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) Header(out any) error
|
func (b *Bind) RespHeader(out any) error
|
||||||
```
|
```
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// Field names should start with an uppercase letter
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `respHeader:"name"`
|
Name string `respHeader:"name"`
|
||||||
Pass string `respHeader:"pass"`
|
Pass string `respHeader:"pass"`
|
||||||
Products []string `respHeader:"products"`
|
Products []string `respHeader:"products"`
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
@ -359,18 +365,22 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
log.Println(p.Name) // john
|
log.Println(p.Name) // john
|
||||||
log.Println(p.Pass) // doe
|
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
|
### 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"
|
```go title="Signature"
|
||||||
func (b *Bind) URI(out any) error
|
func (b *Bind) URI(out any) error
|
||||||
|
@ -379,20 +389,24 @@ func (b *Bind) URI(out any) error
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
// GET http://example.com/user/111
|
// GET http://example.com/user/111
|
||||||
app.Get("/user/:id", func(c fiber.Ctx) error {
|
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
|
## Custom
|
||||||
|
|
||||||
To use custom binders, you have to use this method.
|
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"
|
```go title="Signature"
|
||||||
func (b *Bind) Custom(name string, dest any) error
|
func (b *Bind) Custom(name string, dest any) error
|
||||||
|
@ -402,56 +416,65 @@ func (b *Bind) Custom(name string, dest any) error
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
// My custom binder
|
// My custom binder
|
||||||
customBinder := &customBinder{}
|
type customBinder struct{}
|
||||||
// Name of custom binder, which will be used as Bind().Custom("name")
|
|
||||||
func (*customBinder) Name() string {
|
func (cb *customBinder) Name() string {
|
||||||
return "custom"
|
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"}
|
return []string{"application/yaml"}
|
||||||
}
|
}
|
||||||
// Parse the body and bind it to the out interface
|
|
||||||
func (*customBinder) Parse(c Ctx, out any) error {
|
func (cb *customBinder) Parse(c fiber.Ctx, out any) error {
|
||||||
// parse yaml body
|
// parse YAML body
|
||||||
return yaml.Unmarshal(c.Body(), out)
|
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"
|
// Register custom binder
|
||||||
app.Post("/custom", func(c Ctx) error {
|
app.RegisterCustomBinder(&customBinder{})
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
app.Post("/custom", func(c fiber.Ctx) error {
|
||||||
var user User
|
var user User
|
||||||
// output: {Name:John}
|
// Use Custom binder by name
|
||||||
// Custom binder is used by the name
|
|
||||||
if err := c.Bind().Custom("custom", &user); err != nil {
|
if err := c.Bind().Custom("custom", &user); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// ...
|
|
||||||
return c.JSON(user)
|
return c.JSON(user)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Internally they are also used in the [Body](#body) method.
|
Internally, custom binders 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.
|
The `MIMETypes` method is used to check if the custom binder should be used for the given content type.
|
||||||
|
|
||||||
## Options
|
## 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
|
### Must
|
||||||
|
|
||||||
If you want to handle binder errors automatically, you can use 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 there's an error, it will return the error and set HTTP status to `400 Bad Request`.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (b *Bind) Must() *Bind
|
func (b *Bind) Must() *Bind
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```go title="Example"
|
||||||
|
app.Get("/coffee", func(c fiber.Ctx) error {
|
||||||
|
// => HTTP - GET 301 /teapot
|
||||||
|
return c.Redirect().Status(fiber.StatusMovedPermanently).To("/teapot")
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
### Should
|
### Should
|
||||||
|
|
||||||
To handle binder errors manually, you can prefer Should method.
|
To handle binder errors manually, you can use the `Should` method.
|
||||||
It's default behavior of binder.
|
It's the default behavior of the binder.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (b *Bind) Should() *Bind
|
func (b *Bind) Should() *Bind
|
||||||
|
@ -459,7 +482,7 @@ func (b *Bind) Should() *Bind
|
||||||
|
|
||||||
## SetParserDecoder
|
## 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"
|
```go title="Signature"
|
||||||
func SetParserDecoder(parserConfig fiber.ParserConfig{
|
func SetParserDecoder(parserConfig fiber.ParserConfig{
|
||||||
|
@ -477,34 +500,34 @@ func SetParserDecoder(parserConfig fiber.ParserConfig{
|
||||||
|
|
||||||
type CustomTime time.Time
|
type CustomTime time.Time
|
||||||
|
|
||||||
// String() returns the time in string
|
// String returns the time in string format
|
||||||
func (ct *CustomTime) String() string {
|
func (ct *CustomTime) String() string {
|
||||||
t := time.Time(*ct).String()
|
t := time.Time(*ct).String()
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the converter for CustomTime type format as 2006-01-02
|
// Converter for CustomTime type with format "2006-01-02"
|
||||||
var timeConverter = func(value string) reflect.Value {
|
var timeConverter = func(value string) reflect.Value {
|
||||||
fmt.Println("timeConverter", value)
|
fmt.Println("timeConverter:", value)
|
||||||
if v, err := time.Parse("2006-01-02", value); err == nil {
|
if v, err := time.Parse("2006-01-02", value); err == nil {
|
||||||
return reflect.ValueOf(v)
|
return reflect.ValueOf(CustomTime(v))
|
||||||
}
|
}
|
||||||
return reflect.Value{}
|
return reflect.Value{}
|
||||||
}
|
}
|
||||||
|
|
||||||
customTime := fiber.ParserType{
|
customTime := fiber.ParserType{
|
||||||
Customtype: CustomTime{},
|
CustomType: CustomTime{},
|
||||||
Converter: timeConverter,
|
Converter: timeConverter,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add setting to the Decoder
|
// Add custom type to the Decoder settings
|
||||||
fiber.SetParserDecoder(fiber.ParserConfig{
|
fiber.SetParserDecoder(fiber.ParserConfig{
|
||||||
IgnoreUnknownKeys: true,
|
IgnoreUnknownKeys: true,
|
||||||
ParserType: []fiber.ParserType{customTime},
|
ParserType: []fiber.ParserType{customTime},
|
||||||
ZeroEmpty: true,
|
ZeroEmpty: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Example to use CustomType, you pause custom time format not in RFC3339
|
// Example using CustomTime with non-RFC3339 format
|
||||||
type Demo struct {
|
type Demo struct {
|
||||||
Date CustomTime `form:"date" query:"date"`
|
Date CustomTime `form:"date" query:"date"`
|
||||||
Title string `form:"title" query:"title"`
|
Title string `form:"title" query:"title"`
|
||||||
|
@ -513,31 +536,38 @@ type Demo struct {
|
||||||
|
|
||||||
app.Post("/body", func(c fiber.Ctx) error {
|
app.Post("/body", func(c fiber.Ctx) error {
|
||||||
var d Demo
|
var d Demo
|
||||||
c.BodyParser(&d)
|
if err := c.Bind().Body(&d); err != nil {
|
||||||
fmt.Println("d.Date", d.Date.String())
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("d.Date:", d.Date.String())
|
||||||
return c.JSON(d)
|
return c.JSON(d)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/query", func(c fiber.Ctx) error {
|
app.Get("/query", func(c fiber.Ctx) error {
|
||||||
var d Demo
|
var d Demo
|
||||||
c.QueryParser(&d)
|
if err := c.Bind().Query(&d); err != nil {
|
||||||
fmt.Println("d.Date", d.Date.String())
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("d.Date:", d.Date.String())
|
||||||
return c.JSON(d)
|
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
|
||||||
|
|
||||||
Validation is also possible with the binding methods. You can specify your validation rules using the `validate` struct tag.
|
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"
|
```go title="Example"
|
||||||
import "github.com/go-playground/validator/v10"
|
import "github.com/go-playground/validator/v10"
|
||||||
|
@ -546,18 +576,18 @@ type structValidator struct {
|
||||||
validate *validator.Validate
|
validate *validator.Validate
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validator needs to implement the Validate method
|
// Validate method implementation
|
||||||
func (v *structValidator) Validate(out any) error {
|
func (v *structValidator) Validate(out any) error {
|
||||||
return v.validate.Struct(out)
|
return v.validate.Struct(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup your validator in the config
|
// Setup your validator in the Fiber config
|
||||||
app := fiber.New(fiber.Config{
|
app := fiber.New(fiber.Config{
|
||||||
StructValidator: &structValidator{validate: validator.New()},
|
StructValidator: &structValidator{validate: validator.New()},
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Usage of the validation in the binding methods:
|
### Usage of Validation in Binding Methods
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
type Person struct {
|
type Person struct {
|
||||||
|
@ -568,7 +598,7 @@ type Person struct {
|
||||||
app.Post("/", func(c fiber.Ctx) error {
|
app.Post("/", func(c fiber.Ctx) error {
|
||||||
p := new(Person)
|
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
|
return err
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -578,19 +608,19 @@ 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:
|
You can set default values for fields in the struct by using the `default` struct tag. Supported types:
|
||||||
|
|
||||||
- bool
|
- `bool`
|
||||||
- float variants (float32, float64)
|
- Float variants (`float32`, `float64`)
|
||||||
- int variants (int, int8, int16, int32, int64)
|
- Int variants (`int`, `int8`, `int16`, `int32`, `int64`)
|
||||||
- uint variants (uint, uint8, uint16, uint32, uint64)
|
- Uint variants (`uint`, `uint8`, `uint16`, `uint32`, `uint64`)
|
||||||
- string
|
- `string`
|
||||||
- a slice of the above types. As shown in the example above, **| should be used to separate between slice items**.
|
- A slice of the above types. Use `|` to separate slice items.
|
||||||
- a pointer to one of the above types **(pointer to slice and slice of pointers are not supported)**.
|
- A pointer to one of the above types (**pointers to slices and slices of pointers are not supported**).
|
||||||
|
|
||||||
```go title="Example"
|
```go title="Example"
|
||||||
type Person struct {
|
type Person struct {
|
||||||
Name string `query:"name,default:john"`
|
Name string `query:"name,default=John"`
|
||||||
Pass string `query:"pass"`
|
Pass string `query:"pass"`
|
||||||
Products []string `query:"products,default:shoe|hat"`
|
Products []string `query:"products,default=shoe|hat"`
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Get("/", func(c fiber.Ctx) error {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
@ -600,13 +630,16 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(p.Name) // john
|
log.Println(p.Name) // John
|
||||||
log.Println(p.Pass) // doe
|
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/?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 Tabs from '@theme/Tabs';
|
||||||
import TabItem from '@theme/TabItem';
|
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)
|
- [OnRoute](#onroute)
|
||||||
- [OnName](#onname)
|
- [OnName](#onname)
|
||||||
|
@ -21,7 +21,7 @@ With Fiber v2.30.0, you can execute custom user functions when to run some metho
|
||||||
## Constants
|
## Constants
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Handlers define a function to create hooks for Fiber.
|
// Handlers define functions to create hooks for Fiber.
|
||||||
type OnRouteHandler = func(Route) error
|
type OnRouteHandler = func(Route) error
|
||||||
type OnNameHandler = OnRouteHandler
|
type OnNameHandler = OnRouteHandler
|
||||||
type OnGroupHandler = func(Group) error
|
type OnGroupHandler = func(Group) error
|
||||||
|
@ -34,7 +34,7 @@ type OnMountHandler = func(*App) error
|
||||||
|
|
||||||
## OnRoute
|
## 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"
|
```go title="Signature"
|
||||||
func (h *Hooks) OnRoute(handler ...OnRouteHandler)
|
func (h *Hooks) OnRoute(handler ...OnRouteHandler)
|
||||||
|
@ -42,10 +42,10 @@ func (h *Hooks) OnRoute(handler ...OnRouteHandler)
|
||||||
|
|
||||||
## OnName
|
## 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
|
:::caution
|
||||||
OnName only works with naming routes, not groups.
|
`OnName` only works with named routes, not groups.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
|
@ -73,13 +73,11 @@ func main() {
|
||||||
|
|
||||||
app.Hooks().OnName(func(r fiber.Route) error {
|
app.Hooks().OnName(func(r fiber.Route) error {
|
||||||
fmt.Print("Name: " + r.Name + ", ")
|
fmt.Print("Name: " + r.Name + ", ")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Hooks().OnName(func(r fiber.Route) error {
|
app.Hooks().OnName(func(r fiber.Route) error {
|
||||||
fmt.Print("Method: " + r.Method + "\n")
|
fmt.Print("Method: " + r.Method + "\n")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -104,7 +102,7 @@ func main() {
|
||||||
|
|
||||||
## OnGroup
|
## 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"
|
```go title="Signature"
|
||||||
func (h *Hooks) OnGroup(handler ...OnGroupHandler)
|
func (h *Hooks) OnGroup(handler ...OnGroupHandler)
|
||||||
|
@ -112,10 +110,10 @@ func (h *Hooks) OnGroup(handler ...OnGroupHandler)
|
||||||
|
|
||||||
## OnGroupName
|
## 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
|
:::caution
|
||||||
OnGroupName only works with naming groups, not routes.
|
`OnGroupName` only works with named groups, not routes.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
|
@ -124,7 +122,7 @@ func (h *Hooks) OnGroupName(handler ...OnGroupNameHandler)
|
||||||
|
|
||||||
## OnListen
|
## 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"
|
```go title="Signature"
|
||||||
func (h *Hooks) OnListen(handler ...OnListenHandler)
|
func (h *Hooks) OnListen(handler ...OnListenHandler)
|
||||||
|
@ -134,23 +132,35 @@ func (h *Hooks) OnListen(handler ...OnListenHandler)
|
||||||
<TabItem value="onlisten-example" label="OnListen Example">
|
<TabItem value="onlisten-example" label="OnListen Example">
|
||||||
|
|
||||||
```go
|
```go
|
||||||
app := fiber.New(fiber.Config{
|
package main
|
||||||
DisableStartupMessage: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
app.Hooks().OnListen(func(listenData fiber.ListenData) error {
|
import (
|
||||||
if fiber.IsChild() {
|
"log"
|
||||||
return nil
|
"os"
|
||||||
}
|
|
||||||
scheme := "http"
|
|
||||||
if data.TLS {
|
|
||||||
scheme = "https"
|
|
||||||
}
|
|
||||||
log.Println(scheme + "://" + listenData.Host + ":" + listenData.Port)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
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>
|
</TabItem>
|
||||||
|
@ -158,7 +168,7 @@ app.Listen(":5000")
|
||||||
|
|
||||||
## OnFork
|
## OnFork
|
||||||
|
|
||||||
OnFork is a hook to execute user functions on Fork.
|
`OnFork` is a hook to execute user functions on fork.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (h *Hooks) OnFork(handler ...OnForkHandler)
|
func (h *Hooks) OnFork(handler ...OnForkHandler)
|
||||||
|
@ -166,7 +176,7 @@ func (h *Hooks) OnFork(handler ...OnForkHandler)
|
||||||
|
|
||||||
## OnShutdown
|
## OnShutdown
|
||||||
|
|
||||||
OnShutdown is a hook to execute user functions after Shutdown.
|
`OnShutdown` is a hook to execute user functions after shutdown.
|
||||||
|
|
||||||
```go title="Signature"
|
```go title="Signature"
|
||||||
func (h *Hooks) OnShutdown(handler ...OnShutdownHandler)
|
func (h *Hooks) OnShutdown(handler ...OnShutdownHandler)
|
||||||
|
@ -174,10 +184,10 @@ func (h *Hooks) OnShutdown(handler ...OnShutdownHandler)
|
||||||
|
|
||||||
## OnMount
|
## 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"
|
```go title="Signature"
|
||||||
func (h *Hooks) OnMount(handler ...OnMountHandler)
|
func (h *Hooks) OnMount(handler ...OnMountHandler)
|
||||||
```
|
```
|
||||||
|
|
||||||
<Tabs>
|
<Tabs>
|
||||||
|
@ -193,24 +203,27 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := New()
|
app := fiber.New()
|
||||||
app.Get("/", testSimpleHandler).Name("x")
|
app.Get("/", testSimpleHandler).Name("x")
|
||||||
|
|
||||||
subApp := New()
|
subApp := fiber.New()
|
||||||
subApp.Get("/test", testSimpleHandler)
|
subApp.Get("/test", testSimpleHandler)
|
||||||
|
|
||||||
subApp.Hooks().OnMount(func(parent *fiber.App) error {
|
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
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Mount("/sub", subApp)
|
app.Mount("/sub", subApp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testSimpleHandler(c fiber.Ctx) error {
|
||||||
|
return c.SendString("Hello, Fiber!")
|
||||||
|
}
|
||||||
|
|
||||||
// Result:
|
// Result:
|
||||||
// Mount path of parent app:
|
// Mount path of parent app: /sub
|
||||||
```
|
```
|
||||||
|
|
||||||
</TabItem>
|
</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.
|
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
|
```go
|
||||||
const (
|
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
|
```go
|
||||||
type CommonLogger interface {
|
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
|
### 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
|
```go
|
||||||
log.Info("Hello, World!")
|
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.Info("42 is the answer to life, the universe, and everything")
|
||||||
log.Warn("We are under attack!")
|
log.Warn("We are under attack!")
|
||||||
log.Error("Houston, we have a problem.")
|
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.")
|
log.Panic("The system is down.")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -65,10 +65,10 @@ Logs of different levels can be formatted before printing. All such methods end
|
||||||
|
|
||||||
```go
|
```go
|
||||||
log.Debugf("Hello %s", "boy")
|
log.Debugf("Hello %s", "boy")
|
||||||
log.Infof("%d is the answer to life, the universe, and everything", 233)
|
log.Infof("%d is the answer to life, the universe, and everything", 42)
|
||||||
log.Warnf("We are under attack %s!", "boss")
|
log.Warnf("We are under attack, %s!", "boss")
|
||||||
log.Errorf("%s, we have a problem.", "Master Shifu")
|
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
|
### 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`.
|
Print a message with key-value pairs. If the key and value are not paired correctly, the log will output `KEYVALS UNPAIRED`.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
log.Debugw("", "Hello", "boy")
|
log.Debugw("", "greeting", "Hello", "target", "boy")
|
||||||
log.Infow("", "number", 233)
|
log.Infow("", "number", 42)
|
||||||
log.Warnw("", "job", "boss")
|
log.Warnw("", "job", "boss")
|
||||||
log.Errorw("", "name", "Master Shifu")
|
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.
|
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.
|
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:
|
Here's an example using a custom logger:
|
||||||
|
|
||||||
|
@ -106,22 +106,25 @@ import (
|
||||||
fiberlog "github.com/gofiber/fiber/v3/log"
|
fiberlog "github.com/gofiber/fiber/v3/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ log.AllLogger = (*customLogger)(nil)
|
var _ fiberlog.AllLogger = (*customLogger)(nil)
|
||||||
|
|
||||||
type customLogger struct {
|
type customLogger struct {
|
||||||
stdlog *log.Logger
|
stdlog *log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...
|
// Implement required methods for the AllLogger interface...
|
||||||
// inject your custom logger
|
|
||||||
fiberlog.SetLogger(customLogger)
|
// Inject your custom logger
|
||||||
|
fiberlog.SetLogger(&customLogger{
|
||||||
|
stdlog: log.New(os.Stdout, "CUSTOM ", log.LstdFlags),
|
||||||
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Set Level
|
## Set Level
|
||||||
|
|
||||||
`log.SetLevel` sets the minimum level of logs that will be output. The default log level is `LevelTrace`.
|
`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
|
```go
|
||||||
import "github.com/gofiber/fiber/v3/log"
|
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.
|
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.
|
`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
|
```go
|
||||||
var logger AllLogger = &defaultLogger{
|
var logger fiberlog.AllLogger = &defaultLogger{
|
||||||
stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds),
|
stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds),
|
||||||
depth: 4,
|
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.
|
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
|
```go
|
||||||
// Output to ./test.log file
|
// Output to ./test.log file
|
||||||
f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
log.Fatal("Failed to open log file:", err)
|
||||||
}
|
}
|
||||||
log.SetOutput(f)
|
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`:
|
The following example will write the logs to both `test.log` and `stdout`:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Output to ./test.log file
|
// 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)
|
iw := io.MultiWriter(os.Stdout, file)
|
||||||
log.SetOutput(iw)
|
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.
|
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
|
toc_max_heading_level: 5
|
||||||
---
|
---
|
||||||
|
|
||||||
Is used to redirect the ctx(request) to a different URL/Route.
|
The redirect package is used to redirect the context (request) to a different URL or route.
|
||||||
|
|
||||||
## Redirect Methods
|
## Redirect Methods
|
||||||
|
|
||||||
### To
|
### To
|
||||||
|
|
||||||
Redirects to the URL derived from the specified path, with specified [status](#status), a positive integer that
|
Redirects to the URL derived from the specified path, with a specified [status](#status), a positive integer that corresponds to an HTTP status code.
|
||||||
corresponds to an HTTP status code.
|
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
If **not** specified, status defaults to **302 Found**.
|
If **not** specified, status defaults to **302 Found**.
|
||||||
|
@ -49,10 +48,10 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
### Route
|
### Route
|
||||||
|
|
||||||
Redirects to the specific route along with the parameters and queries.
|
Redirects to a specific route along with the parameters and queries.
|
||||||
|
|
||||||
:::info
|
:::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"
|
```go title="Signature"
|
||||||
|
@ -71,7 +70,7 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
app.Get("/with-queries", 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
|
// /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{
|
Params: fiber.Map{
|
||||||
"name": "fiber",
|
"name": "fiber",
|
||||||
},
|
},
|
||||||
|
@ -90,8 +89,7 @@ app.Get("/user/:name", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
### Back
|
### Back
|
||||||
|
|
||||||
Redirects back to refer URL. It redirects to fallback URL if refer header doesn't exists, with specified status, a
|
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.
|
||||||
positive integer that corresponds to an HTTP status code.
|
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
If **not** specified, status defaults to **302 Found**.
|
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 {
|
app.Get("/", func(c fiber.Ctx) error {
|
||||||
return c.SendString("Home page")
|
return c.SendString("Home page")
|
||||||
})
|
})
|
||||||
|
|
||||||
app.Get("/test", func(c fiber.Ctx) error {
|
app.Get("/test", func(c fiber.Ctx) error {
|
||||||
c.Set("Content-Type", "text/html")
|
c.Set("Content-Type", "text/html")
|
||||||
return c.SendString(`<a href="/back">Back</a>`)
|
return c.SendString(`<a href="/back">Back</a>`)
|
||||||
|
@ -118,7 +117,7 @@ app.Get("/back", func(c fiber.Ctx) error {
|
||||||
## Controls
|
## Controls
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
Method are **chainable**.
|
Methods are **chainable**.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Status
|
### Status
|
||||||
|
@ -126,7 +125,7 @@ Method are **chainable**.
|
||||||
Sets the HTTP status code for the redirect.
|
Sets the HTTP status code for the redirect.
|
||||||
|
|
||||||
:::info
|
:::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"
|
```go title="Signature"
|
||||||
|
@ -145,11 +144,11 @@ app.Get("/coffee", func(c fiber.Ctx) error {
|
||||||
Sets the configuration for the redirect.
|
Sets the configuration for the redirect.
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
Is used in conjunction with the [**Route**](#route) method.
|
It is used in conjunction with the [**Route**](#route) method.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
```go
|
```go title="Definition"
|
||||||
// RedirectConfig A config to use with Redirect().Route()
|
// RedirectConfig is a config to use with Redirect().Route()
|
||||||
type RedirectConfig struct {
|
type RedirectConfig struct {
|
||||||
Params fiber.Map // Route parameters
|
Params fiber.Map // Route parameters
|
||||||
Queries map[string]string // Query map
|
Queries map[string]string // Query map
|
||||||
|
@ -158,7 +157,7 @@ type RedirectConfig struct {
|
||||||
|
|
||||||
### Flash Message
|
### 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
|
#### Messages
|
||||||
|
|
||||||
|
@ -177,7 +176,7 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
#### Message
|
#### 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"
|
```go title="Signature"
|
||||||
func (r *Redirect) Message(key string) *Redirect
|
func (r *Redirect) Message(key string) *Redirect
|
||||||
|
@ -241,10 +240,9 @@ app.Get("/", func(c fiber.Ctx) error {
|
||||||
|
|
||||||
#### WithInput
|
#### WithInput
|
||||||
|
|
||||||
You can send input data by using `WithInput()`.
|
You can send input data by using `WithInput()`. They will be sent as a cookie.
|
||||||
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"
|
```go title="Signature"
|
||||||
func (r *Redirect) WithInput() *Redirect
|
func (r *Redirect) WithInput() *Redirect
|
||||||
|
|
Loading…
Reference in New Issue