<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go Fiber 框架系列教程 02:詳解相關(guān) API 的使用

          共 11649字,需瀏覽 24分鐘

           ·

          2021-09-30 17:12

          閱讀本文大概需要 5 分鐘。

          大家好,我是 polarisxu。

          該系列第一篇文章發(fā)出后,大家褒貶不一,很正常。選什么,不選什么,大家自己評(píng)估,沒有什么是最好的。我這個(gè)系列,更多只是讓大家對(duì) Fiber 有些了解,說(shuō)不定正好合你胃口呢?

          前面對(duì) Fiber 有了大概的印象。今天著重較深入探討 Fiber 相關(guān)功能。

          先從 fiber.New 函數(shù)配置開始。

          01 配置

          大部分 Go 框架,獲得實(shí)例的函數(shù)是不支持配置的,比如 Gin、Echo 等。但 Fiber 框架的 New 函數(shù)支持傳遞配置:

          // New creates a new Fiber named instance.
          //  app := fiber.New()
          // You can pass optional configuration options by passing a Config struct:
          //  app := fiber.New(fiber.Config{
          //      Prefork: true,
          //      ServerHeader: "Fiber",
          //  })
          func New(config ...Config) *App

          一般情況,使用默認(rèn)配置即可(即不手動(dòng)傳遞配置),但有必要了解下,通過(guò)配置,我們能干些什么。

          比如,我們希望響應(yīng)頭中,Server 用自定義的。

          config := fiber.Config{
            ServerHeader: "Go Fiber Framework",
          }
          app := fiber.New(config)

          響應(yīng)頭類似這樣:

          Content-Length: 12
          Content-Type: text/plain; charset=utf-8
          Date: Mon, 20 Sep 2021 14:58:45 GMT
          Server: Go Fiber Framework

          實(shí)際上,在前文模板引擎使用的 Views 就是一個(gè)配置項(xiàng)。

          目前配置 29 項(xiàng)之多,有不少是關(guān)于 HTTP 的配置。所有的配置和說(shuō)明可以在文檔找到:https://docs.gofiber.io/api/fiber#config。建議掃一遍,有一個(gè)印象,方便將來(lái)有需求時(shí)知道在這里找。

          02 路由

          標(biāo)準(zhǔn)庫(kù) net/http 的路由比較簡(jiǎn)單,這大概也是有各種路由庫(kù)(框架)的原因之一。

          最簡(jiǎn)單的路由莫過(guò)于直接匹配,如:

          // 請(qǐng)求匹配到 /about
          app.Get("/about"func(c *fiber.Ctx) error {
            return c.SendString("about")
          })

          命名路由(也叫參數(shù)路由)是一個(gè)強(qiáng)大框架必須的,即提供占位符。比如:

          app.Get("/hello/:username"func(c *fiber.Ctx) error {
            str := fmt.Sprintf("Hello, %s", c.Params("username"))
            return c.SendString(str)
          })

          這個(gè)路由就可以匹配任意的以 /hello/ 開頭的請(qǐng)求,比如:/hello/polarisxu,最后會(huì)輸出:Hello, polarixu

          不過(guò),如果請(qǐng)求的剛好是 /hello/ 呢?Fiber 會(huì)返回 404,報(bào)路由找不到。如果你希望這時(shí)候把 username 當(dāng)空處理,而不是返回 404,可以在 :username 后加一個(gè) ?

          app.Get("/hello/:username?"func(c *fiber.Ctx) error {
            str := fmt.Sprintf("Hello, %s", c.Params("username"))
            return c.SendString(str)
          })

          此外,還有 +* 進(jìn)行通配,區(qū)別在于 + 要求至少要有一個(gè),而 * 可以沒有。通過(guò) c.Params("+")c.Params("*") 獲得對(duì)于的值。

          此外,F(xiàn)iber 還支持有 -. 的復(fù)雜路由,例如:

          // http://localhost:3000/flights/LAX-SFO
          app.Get("/flights/:from-:to"func(c *fiber.Ctx) error {
              fmt.Fprintf(c, "%s-%s\n", c.Params("from"), c.Params("to"))
              return nil // LAX-SFO
          })

          注意,如果路由中需要包含特殊字符,比如 :,需要進(jìn)行轉(zhuǎn)義。

          因?yàn)?Fiber 的目標(biāo)之一是成為 Go 最快、最清晰的 Web 框架,因此對(duì)于更復(fù)雜的路由,比如正則表達(dá)式,F(xiàn)iber 不會(huì)支持。

          Fiber 還提供了方法,返回所有注冊(cè)的路由信息:

          var handler = func(c *fiber.Ctx) error { return nil }

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

              app.Get("/john/:age", handler)
              app.Post("/register", handler)

              data, _ := json.MarshalIndent(app.Stack(), """  ")
              fmt.Println(string(data))

              app.Listen(":3000")
          }

          返回結(jié)果如下:

          [
            [
              {
                "method""GET",
                "path""/john/:age",
                "params": [
                  "age"
                ]
              }
            ],
            [
              {
                "method""HEAD",
                "path""/john/:age",
                "params": [
                  "age"
                ]
              }
            ],
            [
              {
                "method""POST",
                "path""/register",
                "params"null
              }
            ]
          ]

          可以輔助排查路由問(wèn)題。

          03 Static

          上文介紹了服務(wù)靜態(tài)資源的 Static 方法,這里詳細(xì)解釋下。

          Static 方法可以多個(gè)。默認(rèn)情況下,如果目錄下有 index.html 文件,對(duì)目錄的訪問(wèn)會(huì)以該文件作為響應(yīng)。

          app.Static("/static/""./public")

          以上代碼用于項(xiàng)目根目錄下 public 目錄的文件和文件夾。

          此外,Static 方法有第三個(gè)可選參數(shù),以便對(duì) Static 行為進(jìn)行微調(diào),這可以通過(guò) fiber.Static 結(jié)構(gòu)體控制。

          // Static defines configuration options when defining static assets.
          type Static struct {
              // When set to true, the server tries minimizing CPU usage by caching compressed files.
              // This works differently than the github.com/gofiber/compression middleware.
              // Optional. Default value false
              Compress bool `json:"compress"`

              // When set to true, enables byte range requests.
              // Optional. Default value false
              ByteRange bool `json:"byte_range"`

              // When set to true, enables directory browsing.
              // Optional. Default value false.
              Browse bool `json:"browse"`

              // The name of the index file for serving a directory.
              // Optional. Default value "index.html".
              Index string `json:"index"`

              // Expiration duration for inactive file handlers.
              // Use a negative time.Duration to disable it.
              //
              // Optional. Default value 10 * time.Second.
              CacheDuration time.Duration `json:"cache_duration"`

              // The value for the Cache-Control HTTP-header
              // that is set on the file response. MaxAge is defined in seconds.
              //
              // Optional. Default value 0.
              MaxAge int `json:"max_age"`

              // Next defines a function to skip this middleware when returned true.
              //
              // Optional. Default: nil
              Next func(c *Ctx) bool
          }

          上文說(shuō),默認(rèn)情況下,對(duì)目錄訪問(wèn)的索引文件是 index.html,通過(guò) Index 可以改變?cè)撔袨椤H绻胍獑⒂媚夸洖g覽功能,可以設(shè)置 Browse 為 true。

          04 路由處理器

          在前面提到,F(xiàn)iber 有對(duì)應(yīng)的方法支持所有 HTTP Method。除此之外,還有兩個(gè)特殊的方法:Add 和 All。

          Add 方法是所有 HTTP Method 對(duì)應(yīng)方法的底層實(shí)現(xiàn),比如 Get 方法:

          func (app *App) Get(path string, handlers ...Handler) Router {
           return app.Add(MethodHead, path, handlers...).Add(MethodGet, path, handlers...)
          }

          它底層調(diào)用了 Add 方法,做了兩次綁定,分別是 HEAD 和 GET,也就是說(shuō),對(duì)于 Get 方法,支持 HTTP GET 和 HEAD。

          我之前寫過(guò)一篇文章:網(wǎng)友很強(qiáng)大,發(fā)現(xiàn)了Go并發(fā)下載的Bug。Echo 框架,對(duì)于 Get 方法,只是 HTTP GET,不支持 HEAD 請(qǐng)求。目前看,F(xiàn)iber 的做法更合理。如果你真的只需要 GET,可以通過(guò) Add 方法實(shí)現(xiàn)。

          而 All 方法表示支持任意 HTTP Method。

          05 Mount 和 Group

          Mount 方法可以將一個(gè) Fiber 實(shí)例掛載到另一個(gè)實(shí)例。

          func main() {
              micro := fiber.New()
              micro.Get("/doe"func(c *fiber.Ctx) error {
                  return c.SendStatus(fiber.StatusOK)
              })

              app := fiber.New()
              app.Mount("/john", micro) // GET /john/doe -> 200 OK

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

          Group 是路由分組功能,框架基本會(huì)支持該特性,對(duì)于 API 版本控制很有用。

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

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

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

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

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

          06 fiber.Ctx 的方法

          此外,就是 handler 中的參數(shù) fiber.Ctx,這是一個(gè)結(jié)構(gòu)體,包含了眾多的方法(不少都是方便開發(fā)的方法),在使用時(shí)查閱 API 文檔,或訪問(wèn) https://docs.gofiber.io/api/ctx 瀏覽。

          這里介紹幾個(gè)其他框架可能沒有的方法。

          // BodyParser binds the request body to a struct.
          // It supports decoding the following content types based on the Content-Type header:
          // application/json, application/xml, application/x-www-form-urlencoded, multipart/form-data
          // If none of the content types above are matched, it will return a ErrUnprocessableEntity error
          func (c *Ctx) BodyParser(out interface{}) error

          該方法將請(qǐng)求綁定到結(jié)構(gòu)體。(響應(yīng)的也有 QueryParser 方法,主要處理查詢字符串到結(jié)構(gòu)體的綁定)

          看一個(gè)例子:

          type Person struct {
            Name string `json:"name" xml:"name" form:"name"`
            Pass string `json:"pass" xml:"pass" form:"pass"`
          }

          app.Post("/login"func(ctx *fiber.Ctx) error {
            p := new(Person)

            if err := ctx.BodyParser(p); err != nil {
             return err
            }

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

            return ctx.SendString("Success")
          })

          // 運(yùn)行下面的命令進(jìn)行測(cè)試

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

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

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

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

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

          關(guān)于獲取參數(shù),包括路由參數(shù)、查詢參數(shù)、表單參數(shù),F(xiàn)iber 都非常友好的提供了可選的默認(rèn)值形式,也就是說(shuō),當(dāng)沒有傳遞對(duì)應(yīng)值時(shí),我們可以給一個(gè)默認(rèn)值,比如:

          // 10 是可選的。以下代碼表示,當(dāng) page 參數(shù)沒有傳遞,page=10
          page := ctx.Query("page"10)

          默認(rèn)值模式(可選參數(shù))在 Fiber 中有大量使用,這能極大為使用者帶來(lái)方便。

          此外,路由參數(shù)還有 ParamsInt 方法,用來(lái)獲取 int 類型的路由參數(shù)。

          07 小結(jié)

          通過(guò)本文對(duì) Fiber 內(nèi)置功能的介紹,我的感受是,F(xiàn)iber 為開發(fā)者提供了很多便利。如果你沒有用過(guò)其他框架,可能沒有那么大的感受。后續(xù)文章考慮出一個(gè)不同框架相關(guān)寫法的對(duì)比。

          下篇文章介紹 Fiber 的中間件~




          往期推薦


          我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗(yàn)!2012 年接觸 Go 語(yǔ)言并創(chuàng)建了 Go 語(yǔ)言中文網(wǎng)!著有《Go語(yǔ)言編程之旅》、開源圖書《Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)》等。


          堅(jiān)持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場(chǎng)心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長(zhǎng)!也歡迎加我微信好友交流:gopherstudio


          瀏覽 182
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本黄色片网站视频 | 五月天婷婷成人 | 国产精品在线免费视频 | 成人午夜啪免费视频在线观看软件 | 高潮喷水视频 |