Есть ли способ использовать один и тот же запрос.Body в нескольких обработчиках без ручного написания большого количества кода или мне нужно изменить способ, которым я это делаю?
Эта замечательная статья здесь: 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)
}
Есть ли другой метод вместо того, чтобы читать дважды или более одно и то же
request.Body
?Есть ли способ избежать написания всего этого кода в статье (который необходимо поддерживать) и использования библиотек с открытым исходным кодом, которые делают это лучше и пересматриваются тысячами более умных людей, чем я?
Е.Г.: Могу ли я использовать
go-chi
метод?
1 ответ
Уберите байты и используйте по мере необходимости:
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)
}
}