有没有办法在多个处理程序中使用相同的 request.Body 而无需手动编写大量代码,或者我需要改变我这样做的方式?

Fre*_*ors -1 architecture middleware handler go go-chi

这篇很棒的文章在这里:https : //www.alexedwards.net/blog/how-to-properly-parse-a-json-request-body 很好地解释了如何编写 Golang 处理程序。

我需要使用两个处理程序,一个接一个,仅当第一个出现错误时。

像这样:

func main() {
    r := chi.NewRouter()

    r.Post("/api", MyHandlers)
}

func MyHandlers(w http.ResponseWriter, r *http.Request) {

    err := DoSomething(w, r)

    if err != nil {
        println("OMG! Error!")
        DoSomethingWithThisOneInstead(w, r)
    }

}

func DoSomething(w http.ResponseWriter, r *http.Request) error {
    // here I need to read request's Body
    // and I can use io.TeeReader()
    // and I can use all the code in the amazing article example
    // but I don't want to, because it's a lot of code to maintain
    res, err := myLibrary.DoSomething(requestBody)
    if err != nil {
        return err
    }
    render.JSON(w, r, res) // go-chi "render" pkg
    return nil
}

func DoSomethingWithThisOneInstead(w http.ResponseWriter, r *http.Request) {
    // here I need to read request's Body again!
    // and I can use all the code in the amazing article example
    // but I don't want to, because it's a lot of code to maintain
    anotherLibrary.DoSomethingElse.ServeHTTP(w, r)
}
Run Code Online (Sandbox Code Playgroud)
  1. 是否有不同的方法而不是阅读两次或更多次相同的内容request.Body

  2. 有没有办法避免在文章中编写所有代码(需要维护)并使用比我更聪明的数千人修改的更好的开源库?

  3. EG:我可以使用一种go-chi方法吗?

小智 5

吸食字节并根据需要使用:

func MyHandlers(w http.ResponseWriter, r *http.Request) {
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
       // handle error
    }
    r.Body.Close()

    r.Body = ioutil.NopCloser(bytes.NewReader(body))
    err := DoSomething(w, r)

    if err != nil {
        println("OMG! Error!")
        r.Body = ioutil.NopCloser(bytes.NewReader(body))
        DoSomethingWithThisOneInstead(w, r)
    }

}
Run Code Online (Sandbox Code Playgroud)