go学习巩固知识点(1)mod 理解 ,中间件搭建

最近 在看go 的相关学习教程,巩固一些知识点。
主要 代码 来自 《G01 Go 实战:Web 入门》 学习中的代码

mod

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 协议》,转载必须注明作者和本文链接
讨论数量: 4

不行啊,根本跑不起来,无法处理简单的请求

3年前 评论

可以 贴下 图 我看下吗

3年前 评论

@hardykay 我又 加了点代码 ,你看下是否 能理解 你说的简单的请求

3年前 评论
hardykay 3年前

file 帮我看看哪里出了问题,我直接用了示例1,golang是1.6.

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!