带有示例的在线 API 文档,因此您可以立即开始使用 Fiber 构建 Web 应用程序!
Fiber是一个受Express启发的Web 框架,构建在Fasthttp 之上,这是Go中最快的HTTP 引擎。旨在简化快速开发的工作,同时考虑到零内存分配和性能。
这些文档适用于2020年 9 月 15 日发布的Fiber v2 。
安装
首先,下载并安装 Go。1.14或更高是必需的。
使用以下命令完成安装:
go get github.com/gofiber/fiber/v2
零分配
Fiber.Ctx返回的某些值默认情况下不是不可变的。
因为 Fiber 针对高性能进行了优化,所以从fiber.Ctx返回的值默认情况下不是不可变的,并且会在请求之间重复使用。根据经验,您只能在处理程序中使用上下文值,并且不得保留任何引用。一旦您从处理程序返回,您从上下文中获得的任何值都将在未来的请求中重新使用,并将在您的脚下发生变化。这是一个例子:func handler(c *fiber.Ctx) error {// Variable is only valid within this handlerresult := c.Params("foo")// ...}
如果您需要在处理程序之外保留这些值,请使用内置的copy 复制其底层缓冲区。这是一个持久化字符串的示例:
func handler(c *fiber.Ctx) error {// Variable is only valid within this handlerresult := c.Params("foo")// Make a copybuffer := make([]byte, len(result))copy(buffer, result)resultCopy := string(buffer)// Variable is now valid forever// ...}
我们创建了一个ImmutableString执行上述操作的自定义函数,该函数在gofiber/utils包中可用。
app.Get("/:foo", func(c *fiber.Ctx) error {// Variable is now immutableresult := utils.ImmutableString(c.Params("foo"))// ...})
或者,您也可以使用该Immutable设置。它将使从上下文返回的所有值不可变,允许您将它们保存在任何地方。当然,这是以性能为代价的。
下面嵌入本质上是您可以创建的最简单的Fiber应用程序:
package mainimport "github.com/gofiber/fiber/v2"func main() {app := fiber.New()app.Get("/", func(c *fiber.Ctx) error {return c.SendString("Hello, World!")})app.Listen(":3000")}
浏览到http://localhost:3000,您应该Hello, World!在页面上看到。
基本路由
路由是指确定应用程序如何响应客户端对特定端点的请求,该端点是 URI(或路径)和特定的 HTTP 请求方法(GET、PUT、POST等)。
每个路由可以有多个处理函数,当路由匹配时执行。
路由定义采用以下结构:
// Function signatureapp.Method(path string, ...func(*fiber.Ctx) error)
- app是Fiber的一个实例
- Method是一个HTTP 请求方法: GET, PUT, POST, 等等。
- path是服务器上的虚拟路径
- func(*fiber.Ctx) error是一个回调函数,包含路由匹配时执行的上下文
简单路线
// Respond with "Hello, World!" on root path, "/"app.Get("/", func(c *fiber.Ctx) error {return c.SendString("Hello, World!")})
参数
// GET http://localhost:8080/hello%20worldapp.Get("/:value", func(c *fiber.Ctx) error {return c.SendString("value: " + c.Params("value"))// => Get request with value: hello world})
可选参数
// GET http://localhost:3000/johnapp.Get("/:name?", func(c *fiber.Ctx) error {if c.Params("name") != "" {return c.SendString("Hello " + c.Params("name"))// => Hello john}return c.SendString("Where is john?")})
通配符
// GET http://localhost:3000/api/user/johnapp.Get("/api/*", func(c *fiber.Ctx) error {return c.SendString("API path: " + c.Params("*"))// => API path: user/john})
静态文件
要为图像、CSS和JavaScript文件等静态文件提供服务,请将您的函数处理程序替换为文件或目录字符串。
函数签名:
app.Static(prefix, root string, config ...Static)
使用以下代码在名为 的目录中提供文件./public:
app := fiber.New()app.Static("/", "./public")app.Listen(":3000")
现在,您可以加载目录中的./public文件:
http://localhost:8080/hello.htmlhttp://localhost:8080/js/jquery.jshttp://localhost:8080/css/style.css
优雅关闭
package mainimport ("log""io""time""net/http""github.com/gofiber/fiber/v2")func startHttpServer() *http.Server {app := fiber.New()app.Get("/", func(c *fiber.Ctx) error {return c.SendString("Hello, World!")})go func() {if err := app.Listen(":3000"); err != nil {// cannot panic, because this probably is an intentional closelog.Printf("Httpserver: ListenAndServe() error: %s", err)}}()// returning reference so caller can call Shutdown()return app}func main() {log.Printf("main: starting HTTP server")app := startHttpServer()log.Printf("main: serving for 10 seconds")time.Sleep(10 * time.Second)log.Printf("main: stopping HTTP server")// now close the server gracefully ("shutdown")// timeout could be given instead of nil as a https://golang.org/pkg/context/if err := app.Shutdown(nil); err != nil {panic(err) // failure/timeout shutting down the server gracefully}log.Printf("main: done. exiting")}
官方优雅关闭:
package mainimport "fmt"import "os"import "os/signal"import "syscall"func main() {// Go signal notification works by sending `os.Signal`// values on a channel. We'll create a channel to// receive these notifications (we'll also make one to// notify us when the program can exit).sigs := make(chan os.Signal, 1)done := make(chan bool, 1)// `signal.Notify` registers the given channel to// receive notifications of the specified signals.signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)// This goroutine executes a blocking receive for// signals. When it gets one it'll print it out// and then notify the program that it can finish.go func() {sig := <-sigsfmt.Println()fmt.Println(sig)done <- true}()// The program will wait here until it gets the// expected signal (as indicated by the goroutine// above sending a value on `done`) and then exit.fmt.Println("awaiting signal")<-donefmt.Println("exiting")}
示例代码如下:
https://stackoverflow.com/questions/39320025/how-to-stop-http-listenandserve
package mainimport ("log""io""time""net/http")func startHttpServer() *http.Server {srv := &http.Server{Addr: ":8080"}http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {io.WriteString(w, "hello world\n")})go func() {if err := srv.ListenAndServe(); err != nil {// cannot panic, because this probably is an intentional closelog.Printf("Httpserver: ListenAndServe() error: %s", err)}}()// returning reference so caller can call Shutdown()return srv}func main() {log.Printf("main: starting HTTP server")srv := startHttpServer()log.Printf("main: serving for 10 seconds")time.Sleep(10 * time.Second)log.Printf("main: stopping HTTP server")// now close the server gracefully ("shutdown")// timeout could be given instead of nil as a https://golang.org/pkg/context/if err := srv.Shutdown(nil); err != nil {panic(err) // failure/timeout shutting down the server gracefully}log.Printf("main: done. exiting")}
