Fiber v3 目前处于 Beta 测试阶段,并正在积极开发中。虽然它提供了一些令人兴奋的新功能,但请注意,它可能并不稳定,无法用于生产环境。我们建议在关键任务应用程序中使用最新的稳定版本 (v2.x)。如果您选择使用 v3,请做好应对潜在错误和重大更改的准备。请务必查看官方文档和发行说明以获取更新,并谨慎操作。祝您编码愉快!🚀
Fiber 需要 Go 版本 1.24
或更高版本 才能运行。如果您需要安装或升级 Go,请访问 官方 Go 下载页面。要开始设置您的项目,请为您的项目创建一个新目录并导航到该目录。然后,在终端中执行以下命令,使用 Go 模块初始化您的项目:
go mod init github.com/your/repo
要了解更多关于 Go 模块及其工作原理的信息,您可以查看 使用 Go 模块 博客文章。
设置项目后,您可以使用 go get
命令安装 Fiber:
go get -u github.com/gofiber/fiber/v3
此命令将获取 Fiber 包并将其添加到项目的依赖项中,以便您开始使用 Fiber 构建 Web 应用程序。
Fiber 入门非常简单。这是一个基本示例,用于创建一个简单的 Web 服务器,该服务器在根路径上响应“Hello, World 👋!”。此示例演示了如何初始化新的 Fiber 应用、设置路由以及启动服务器。
package main
import (
"log"
"github.com/gofiber/fiber/v3"
)
func main() {
// Initialize a new Fiber app
app := fiber.New()
// Define a route for the GET method on the root path '/'
app.Get("/", func(c fiber.Ctx) error {
// Send a string response to the client
return c.SendString("Hello, World 👋!")
})
// Start the server on port 3000
log.Fatal(app.Listen(":3000"))
}
这个简单的服务器易于设置和运行。它介绍了 Fiber 的核心概念:应用初始化、路由定义和启动服务器。只需运行这个 Go 程序,然后在浏览器中访问 http://localhost:3000
即可查看消息。
Fiber 针对高性能进行了优化,这意味着从 fiber.Ctx 返回的值默认情况下不是不可变的,并且将在请求之间重复使用。根据经验,必须仅在处理程序中使用上下文值,并且不得保留任何引用。从处理程序返回后,从上下文获取的任何值都将在未来的请求中重复使用。访问我们的文档 了解更多信息。
这些测试由 TechEmpower 执行。如果您想查看所有结果,请访问我们的 Wiki。
新从 Node.js 迁移到 Go 的 Go 开发者在开始构建 Web 应用程序或微服务之前,需要经历一段学习曲线。Fiber 作为一个 Web 框架,秉承极简主义的理念,遵循 UNIX 风格,旨在帮助 Go 新手快速进入 Go 的世界,并享受到热情友好的体验。
Fiber 的灵感源自互联网上最流行的 Web 框架 Express。我们将 Express 的易用性与 Go 的卓越性能完美结合。如果您曾经使用过 Node.js(使用 Express 或类似框架)实现过 Web 应用程序,那么许多方法和原则对您来说可能非常熟悉。
我们通过 issues、Discord 频道 以及互联网上的各个平台,认真倾听用户的意见,致力于打造一个快速、灵活且友好的 Go Web 框架,适用于任何任务、任何截止日期以及任何开发者技能!就像 Express 在 JavaScript 世界中所做的那样。
net/http
接口。当您需要与该生态系统集成时,请使用 adaptor 中间件 在 Fiber 和 net/http
之间桥接处理程序和中间件。Fiber 可以通过使用 adaptor 中间件 与标准库并行运行。它可以双向转换处理程序和中间件,甚至允许您将 Fiber 应用挂载到 net/http
服务器中。
以下列出了一些常见的示例。如果您想查看更多代码示例,请访问我们的 Recipes 代码库 或访问我们托管的 API 文档。
package main
import (
"fmt"
"log"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
// GET /api/register
app.Get("/api/*", func(c fiber.Ctx) error {
msg := fmt.Sprintf("✋ %s", c.Params("*"))
return c.SendString(msg) // => ✋ register
})
// GET /flights/LAX-SFO
app.Get("/flights/:from-:to", func(c fiber.Ctx) error {
msg := fmt.Sprintf("💸 From: %s, To: %s", c.Params("from"), c.Params("to"))
return c.SendString(msg) // => 💸 From: LAX, To: SFO
})
// GET /dictionary.txt
app.Get("/:file.:ext", func(c fiber.Ctx) error {
msg := fmt.Sprintf("📃 %s.%s", c.Params("file"), c.Params("ext"))
return c.SendString(msg) // => 📃 dictionary.txt
})
// GET /john/75
app.Get("/:name/:age/:gender?", func(c fiber.Ctx) error {
msg := fmt.Sprintf("👴 %s is %s years old", c.Params("name"), c.Params("age"))
return c.SendString(msg) // => 👴 john is 75 years old
})
// GET /john
app.Get("/:name", func(c fiber.Ctx) error {
msg := fmt.Sprintf("Hello, %s 👋!", c.Params("name"))
return c.SendString(msg) // => Hello john 👋!
})
log.Fatal(app.Listen(":3000"))
}
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
app.Get("/api/*", func(c fiber.Ctx) error {
msg := fmt.Sprintf("✋ %s", c.Params("*"))
return c.SendString(msg) // => ✋ register
}).Name("api")
route := app.GetRoute("api")
data, _ := json.MarshalIndent(route, "", " ")
fmt.Println(string(data))
// Prints:
// {
// "method": "GET",
// "name": "api",
// "path": "/api/*",
// "params": [
// "*1"
// ]
// }
log.Fatal(app.Listen(":3000"))
}
package main
import (
"log"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/static"
)
func main() {
app := fiber.New()
// Serve static files from the "./public" directory
app.Get("/*", static.New("./public"))
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Get("/prefix*", static.New("./public"))
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
// Serve a single file for any unmatched routes
app.Get("*", static.New("./public/index.html"))
// => http://localhost:3000/any/path/shows/index.html
log.Fatal(app.Listen(":3000"))
}
package main
import (
"fmt"
"log"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
// Middleware that matches any route
app.Use(func(c fiber.Ctx) error {
fmt.Println("🥇 First handler")
return c.Next()
})
// Middleware that matches all routes starting with /api
app.Use("/api", func(c fiber.Ctx) error {
fmt.Println("🥈 Second handler")
return c.Next()
})
// GET /api/list
app.Get("/api/list", func(c fiber.Ctx) error {
fmt.Println("🥉 Last handler")
return c.SendString("Hello, World 👋!")
})
log.Fatal(app.Listen(":3000"))
}
📖 Group
package main
import (
"log"
"github.com/gofiber/fiber/v3"
)
func middleware(c fiber.Ctx) error {
log.Println("Middleware executed")
return c.Next()
}
func handler(c fiber.Ctx) error {
return c.SendString("Handler response")
}
func main() {
app := fiber.New()
// Root API group with middleware
api := app.Group("/api", middleware) // /api
// API v1 routes
v1 := api.Group("/v1", middleware) // /api/v1
v1.Get("/list", handler) // /api/v1/list
v1.Get("/user", handler) // /api/v1/user
// API v2 routes
v2 := api.Group("/v2", middleware) // /api/v2
v2.Get("/list", handler) // /api/v2/list
v2.Get("/user", handler) // /api/v2/user
log.Fatal(app.Listen(":3000"))
}
📖 Logger
package main
import (
"log"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/logger"
)
func main() {
app := fiber.New()
// Use Logger middleware
app.Use(logger.New())
// Define routes
app.Get("/", func(c fiber.Ctx) error {
return c.SendString("Hello, Logger!")
})
log.Fatal(app.Listen(":3000"))
}
📖 CORS
package main
import (
"log"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/cors"
)
func main() {
app := fiber.New()
// Use CORS middleware with default settings
app.Use(cors.New())
// Define routes
app.Get("/", func(c fiber.Ctx) error {
return c.SendString("CORS enabled!")
})
log.Fatal(app.Listen(":3000"))
}
Check CORS by passing any domain in Origin
header:
curl -H "Origin: http://example.com" --verbose http://localhost:3000
package main
import (
"log"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
// Define routes
app.Get("/", static.New("./public"))
app.Get("/demo", func(c fiber.Ctx) error {
return c.SendString("This is a demo page!")
})
app.Post("/register", func(c fiber.Ctx) error {
return c.SendString("Registration successful!")
})
// Middleware to handle 404 Not Found
app.Use(func(c fiber.Ctx) error {
return c.SendStatus(fiber.StatusNotFound) // => 404 "Not Found"
})
log.Fatal(app.Listen(":3000"))
}
📖 JSON
package main
import (
"log"
"github.com/gofiber/fiber/v3"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
app := fiber.New()
// Route that returns a JSON object
app.Get("/user", func(c fiber.Ctx) error {
return c.JSON(&User{"John", 20})
// => {"name":"John", "age":20}
})
// Route that returns a JSON map
app.Get("/json", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{
"success": true,
"message": "Hi John!",
})
// => {"success":true, "message":"Hi John!"}
})
log.Fatal(app.Listen(":3000"))
}
package main
import (
"log"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/websocket"
)
func main() {
app := fiber.New()
// WebSocket route
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
defer c.Close()
for {
// Read message from client
mt, msg, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", msg)
// Write message back to client
err = c.WriteMessage(mt, msg)
if err != nil {
log.Println("write:", err)
break
}
}
}))
log.Fatal(app.Listen(":3000"))
// Connect via WebSocket at ws://localhost:3000/ws
}
package main
import (
"bufio"
"fmt"
"log"
"time"
"github.com/gofiber/fiber/v3"
"github.com/valyala/fasthttp"
)
func main() {
app := fiber.New()
// Server-Sent Events route
app.Get("/sse", func(c fiber.Ctx) error {
c.Set("Content-Type", "text/event-stream")
c.Set("Cache-Control", "no-cache")
c.Set("Connection", "keep-alive")
c.Set("Transfer-Encoding", "chunked")
c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
var i int
for {
i++
msg := fmt.Sprintf("%d - the time is %v", i, time.Now())
fmt.Fprintf(w, "data: Message: %s\n\n", msg)
fmt.Println(msg)
w.Flush()
time.Sleep(5 * time.Second)
}
})
return nil
})
log.Fatal(app.Listen(":3000"))
}
📖 Recover
package main
import (
"log"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/recover"
)
func main() {
app := fiber.New()
// Use Recover middleware to handle panics gracefully
app.Use(recover.New())
// Route that intentionally panics
app.Get("/", func(c fiber.Ctx) error {
panic("normally this would crash your app")
})
log.Fatal(app.Listen(":3000"))
}
📖 Config
package main
import (
"log"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New(fiber.Config{
// Configure trusted proxies - WARNING: Only trust proxies you control
// Using TrustProxy: true with unrestricted IPs can lead to IP spoofing
TrustProxy: true,
TrustProxyConfig: fiber.TrustProxyConfig{
Proxies: []string{"10.0.0.0/8", "172.16.0.0/12"}, // Example: Internal network ranges only
},
ProxyHeader: fiber.HeaderXForwardedFor,
})
// Define routes
app.Get("/", func(c fiber.Ctx) error {
return c.SendString("Trusted Proxy Configured!")
})
log.Fatal(app.Listen(":3000"))
}
以下是 Fiber 框架中包含的中间件列表。
中间件 | 描述 |
---|---|
adaptor | 用于 net/http 处理程序与 Fiber 请求处理程序之间的转换。 |
basicauth | 提供 HTTP 基本身份验证。如果凭据有效,它会调用下一个处理程序;如果凭据缺失或无效,它会返回 401 Unauthorized 错误。 |
cache | 拦截并缓存 HTTP 响应。 |
compress | Fiber 的压缩中间件,支持 deflate 、gzip 、brotli 和 zstd 。 |
cors | 使用各种选项启用跨域资源共享 (CORS)。 |
csrf | 防止 CSRF 攻击。 |
earlydata | 添加对 TLS 1.3 早期数据(“0-RTT”)功能的支持。 |
encryptcookie | 加密 cookie 值的中间件。 |
envvar | 通过提供可选配置来公开环境变量。 |
etag | 允许缓存更高效并节省带宽,因为如果内容未更改,Web 服务器无需重新发送完整响应。 |
expvar | 通过其 HTTP 服务器运行时以 JSON 格式公开的变量提供服务。 |
favicon | 如果提供了文件路径,则忽略日志中的图标或从内存中提供服务。 |
healthcheck | Fiber 的活跃度和就绪度探测。 |
helmet | 通过设置各种 HTTP 标头来帮助保护您的应用。 |
idempotency | 允许容错 API,其中重复的请求不会错误地导致在服务器端多次执行相同的操作。 |
keyauth | 添加对基于密钥的身份验证的支持。 |
limiter | 为 Fiber 添加速率限制支持。用于限制对公共 API 和/或端点(例如密码重置)的重复请求。 |
logger | HTTP 请求/响应记录器。 |
pprof | 以 pprof 格式提供运行时分析数据。 |
proxy | 允许您将请求代理到多个服务器。 |
recover | 从堆栈链中任何位置的 panic 中恢复,并将控制权交给集中式 ErrorHandler。 |
redirect | 重定向中间件。 |
requestid | 为每个请求添加一个请求 ID。 |
rewrite | 根据提供的规则重写 URL 路径。这有助于向后兼容,或者创建更简洁、更具描述性的链接。 |
session | 会话中间件。注意:此中间件使用我们的 Storage 包。 |
skip | 如果谓词为 true,则跳过包装处理程序的中间件。 |
static | Fiber 的静态中间件,用于处理静态文件,例如 images、CSS 和 JavaScript。 |
timeout | 为请求添加最大时间,如果超出则转发到 ErrorHandler。 |
为确保您的贡献已准备好提交 Pull Request,请使用以下 Makefile
命令。这些工具有助于维护代码质量和一致性。
运行这些命令以确保您的代码符合项目标准和最佳实践。
版权所有 (c) 2019-至今 Fenny 和 Contributors。“Fiber”是免费开源软件,遵循 MIT 许可证。官方徽标由 Vic Shóstak 设计,并遵循 知识共享 许可证 (CC BY-SA 4.0 International) 分发。