Golang中从github.com/valyala/fasthttp迁移到net/http的方法

Golang中从github.com/valyala/fasthttp迁移到net/http的方法

func main() {
    flag.Parse()
    h := requestHandler
    if *compress {
        h = fasthttp.CompressHandler(h)
    }
    if err := fasthttp.ListenAndServe(*addr, h); err != nil {
        log.Fatalf("Error in ListenAndServe: %s", err)
    }
}
func requestHandler(ctx *fasthttp.RequestCtx) {
    var request_api = string(ctx.RequestURI())

大家好,

我正在编写一个Go程序,最初有人建议使用fasthttp,但现在我得知它不再受支持,需要迁移到Net/http。

如何迁移到Net/http?我当前的代码如下:


更多关于Golang中从github.com/valyala/fasthttp迁移到net/http的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中从github.com/valyala/fasthttp迁移到net/http的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以下是迁移到 net/http 的步骤和示例代码。首先,fasthttpnet/http 的 API 设计不同,因此需要调整处理函数和服务器设置。

步骤说明:

  1. 替换导入包:从 github.com/valyala/fasthttp 改为 net/http
  2. 修改处理函数签名fasthttp 使用 *fasthttp.RequestCtx,而 net/http 使用 http.ResponseWriter*http.Request
  3. 调整请求处理逻辑:例如,获取请求 URI 的方式不同。
  4. 更新服务器启动代码:使用 http.ListenAndServe 替代 fasthttp.ListenAndServe,并移除 fasthttp 特定的中间件(如 CompressHandler),改用 net/http 的等效功能(如内置的压缩支持或第三方中间件)。

迁移后的示例代码:

以下代码将您的示例迁移到 net/http。假设 compress 标志用于启用 gzip 压缩,可以使用标准库的 gzip 包或第三方中间件实现。这里使用标准库的 gzip 处理作为示例。

package main

import (
    "compress/gzip"
    "flag"
    "log"
    "net/http"
    "strings"
)

var (
    addr     = flag.String("addr", ":8080", "TCP address to listen to")
    compress = flag.Bool("compress", false, "Whether to enable gzip compression")
)

func main() {
    flag.Parse()
    http.HandleFunc("/", requestHandler) // 注册处理函数到根路径
    handler := http.DefaultServeMux
    if *compress {
        // 使用 gzip 中间件包装处理函数
        handler = gzipHandler(handler)
    }
    if err := http.ListenAndServe(*addr, handler); err != nil {
        log.Fatalf("Error in ListenAndServe: %s", err)
    }
}

// gzipHandler 是一个简单的 gzip 压缩中间件,包装 http.Handler
func gzipHandler(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 检查客户端是否支持 gzip
        if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
            w.Header().Set("Content-Encoding", "gzip")
            gz := gzip.NewWriter(w)
            defer gz.Close()
            // 使用 gzip 写入器包装响应
            gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
            h.ServeHTTP(gzw, r)
        } else {
            h.ServeHTTP(w, r)
        }
    })
}

// gzipResponseWriter 包装 http.ResponseWriter 以支持 gzip
type gzipResponseWriter struct {
    http.ResponseWriter
    Writer *gzip.Writer
}

func (g gzipResponseWriter) Write(b []byte) (int, error) {
    return g.Writer.Write(b)
}

// requestHandler 是处理 HTTP 请求的函数,使用 net/http 的签名
func requestHandler(w http.ResponseWriter, r *http.Request) {
    requestAPI := r.URL.String() // 获取请求 URI,类似于 fasthttp 的 RequestURI()
    // 示例:写入响应
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("Request URI: " + requestAPI))
}

关键变化解释:

  • 处理函数requestHandler 现在接受 http.ResponseWriter*http.Request 参数。使用 r.URL.String() 获取完整的请求 URI,这对应于 fasthttp 中的 string(ctx.RequestURI())
  • 服务器启动:使用 http.ListenAndServe 并传递处理程序。如果启用压缩,则通过自定义 gzipHandler 中间件实现 gzip 压缩(net/http 没有内置的压缩处理器,但可以轻松添加)。
  • 压缩处理:在 fasthttp 中,CompressHandler 是内置的,但在 net/http 中需要手动实现或使用第三方库。上述代码提供了一个简单的 gzip 中间件示例。

这个迁移保持了原有功能,同时移除了对 fasthttp 的依赖。根据实际需求,您可能需要进一步调整错误处理或添加其他中间件。

回到顶部