go學習鞏固知識點(1)mod 理解 ,中介軟體搭建

lai發表於2021-02-26

最近 在看go 的相關學習教程,鞏固一些知識點。
主要 程式碼 來自 《G01 Go 實戰:Web 入門》 學習中的程式碼

mod 是類似 php 的composer ,node 的 npm 的依賴管理工具。它使專案可以在任意地方建立而不再像1.11之前要在$GOPATH/src 下建立專案

mod 開啟方法

phpstorm

  • 開啟 perferences

cli

  • 建立 mod 檔案
    go mod init
  • 設定代理
    go env -w  GOPROXY=https://goproxy.cn

    mod的常用命令

  • go get 拉取新的依賴
  • 拉取最新的版本(優先擇取 tag):go get golang.org/x/text@latest
  • 拉取 master 分支的最新 commit:go get golang.org/x/text@master
  • 拉取 tag 為 v0.3.2 的 commit:go get golang.org/x/text@v0.3.2
  • 拉取 hash 為 342b231 的 commit,最終會被轉換為 v0.3.2:go get golang.org/x/text@342b2e
  • go get -u 更新現有的依賴
  • go mod download 下載 go.mod 檔案中指明的所有依賴
  • go mod tidy 整理現有的依賴
  • go mod graph 檢視現有的依賴結構
  • go mod init 生成 go.mod 檔案 (Go 1.13 中唯一一個可以生成 go.mod 檔案的子命令)
  • go mod edit 編輯 go.mod 檔案
  • go mod vendor 匯出現有的所有依賴 (事實上 Go modules 正在淡化 Vendor 的概念)
  • go mod verify 校驗一個模組是否被篡改過
  • go clean -modcache 清楚快取

路由器的選取 HttpRouter & gorilla/mux

根據Summer大佬的說明,擷取大佬的想法

HttpRouter 是目前來講速度最快的路由器,且被知名框架 Gin 所採用。
不選擇 HttpRouter 的原因是其功能略顯單一,沒有路由命名功能,不符合我們的要求。
HttpRouter 和 Gin 比較適合在要求高效能,且路由功能要求相對簡單的專案中,如 API 或微服務。
在全棧的 Web 開發中,gorilla/mux 在效能上雖然有所不及,但是功能強大,比較實用。

安裝 gorilla/mux

go get -u github.com/gorilla/mux 

開始 擼程式碼

先寫個簡單的訪問

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
    "strings"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
    _, _ = fmt.Fprint(w, "<h1>Hello, 歡迎來到 goblog!</h1>")
}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", homeHandler).Methods("GET").Name("home")

    _ = http.ListenAndServe(":3000")
}

建立 中間 使每次響應都 設定表頭

  • 使用 mux.Use() 來載入 中介軟體
  • 整理後的 程式碼
package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
    "strings"
)
func homeHandler(w http.ResponseWriter, r *http.Request) {
    _, _ = fmt.Fprint(w, "<h1>Hello, 歡迎來到 goblog!</h1>")
}

func forceHTMLMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 1. 設定標頭
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
        // 2. 繼續處理請求
        next.ServeHTTP(w, r)
    })
}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", homeHandler).Methods("GET").Name("home")

    router.Use(forceHTMLMiddleware)

    _ = http.ListenAndServe(":3000")
}

利用中介軟體 解決 url ‘/‘ 的問題

  • 雖然 Gorilla Mux 提供了一個 StrictSlash(value bool) 函式 ,但是它是利用重定向又請求了一次,並且如果是 post 請求 ,重定向之後 又變成get
  • 決定利用 中介軟體 解決。
package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
    "strings"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
    _, _ = fmt.Fprint(w, "<h1>Hello, 歡迎來到 goblog!</h1>")
}

func me(w http.ResponseWriter, r *http.Request) {
    _, _ = fmt.Fprint(w, "<h1>Hello, 歡迎來到 個人中心!</h1>")
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusNotFound)
    _, _ = fmt.Fprint(w, "<h1>請求頁面未找到 :(</h1><p>如有疑惑,請聯絡我們。</p>")
}

func forceHTMLMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 1. 設定標頭
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
        // 2. 繼續處理請求
        next.ServeHTTP(w, r)
    })
}

func removeTrailingSlash(handler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 1. 除首頁以外,移除所有請求路徑後面的斜杆
        if r.URL.Path != "/" {
            r.URL.Path = strings.TrimSuffix(r.URL.Path, "/")
        }

        // 2. 將請求傳遞下去
        handler.ServeHTTP(w, r)
    })
}

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", homeHandler).Methods("GET").Name("home")
    router.HandleFunc("/me", me).Methods("GET").Name("me")

    // 自定義 404 頁面
    router.NotFoundHandler = http.HandlerFunc(notFoundHandler)

    router.Use(forceHTMLMiddleware)

    _ = http.ListenAndServe(":3000", removeTrailingSlash(router))
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章