在 Golang 中使用中间件获取主体时出错

问题描述 投票:0回答:1

我正在创建一个端点,并使用 JSONContentExtractor 中间件来获取上下文,但如果我使用它,我无法获取处理程序中的 Body。

package main

import (
"encoding/json"
"fmt"
"log"
"net/http"

    "github.com/gorilla/mux"
    "go.mnc.gt/middleware"

)

type RequestBody struct {
Id        int    `json:"id"`
FirstName string `json:"first_name"`
}

func main() {
log.Println("starting API server")

    //create a new router
    router := mux.NewRouter()
    log.Println("creating routes")
    
    // Add external routes wthout encryption
    middlewaresChainWithoutSessionAndWithoutEncryption := middleware.MiddlewaresChain(middleware.JSONContentExtractor)
    
    //specify endpoints
    router.HandleFunc("/personsMiddleware", middlewaresChainWithoutSessionAndWithoutEncryption(Persons)).Methods("POST")
    http.Handle("/", router)
    
    //start and listen to requests
    http.ListenAndServe(":8080", router)

}

func Persons(w http.ResponseWriter, r \*http.Request) {
log.Println("entering persons end point")

    var requestBody RequestBody
    err := json.NewDecoder(r.Body).Decode(&requestBody)
    if err != nil {
        http.Error(w, "Error al decodificar el cuerpo de la petición", http.StatusBadRequest)
        return
    }
    
    fmt.Printf("Cuerpo de la petición: %+v\n", requestBody)

}

在中间件中,可以读取主体,并且在跟踪中,它也会出现,但我无法再次从主体中取出它,我知道这是可能的,因为中间件通过行

r.Body = ioutil.NopCloser(bytes.NewBuffer(rawRequestBody))
使主体再次可用

这是我遇到的错误

2023/11/09 13:39:37 starting API server
2023/11/09 13:39:37 creating routes
2023-11-09T13:39:38.686-0600    DEBUG   [email protected]/json_content_extractor_middleware.go:34   request body: {
    "id": 1,
    "first_name": "first_name",
    "last_name": "last_name"
}
2023/11/09 13:39:38 entering persons end point
Cuerpo de la petición: {Id:0 FirstName: LastName:}
2023-11-09T13:39:38.686-0600    ERROR   [email protected]/event_publisher.go:27  
    Event publisher not configured. Event may be lost
        /Users/tribal/go/pkg/mod/go.mnc.gt/[email protected]/event_publisher.go:27   (go.mnc.gt/trace.publishEvent)
2023-11-09T13:39:38.687-0600    ERROR   [email protected]/event_publisher.go:37  Unsent event: {"traceID":":1699558778686647000 /personsMiddleware","httpMethod":"POST","host":"localhost:8080","ipAddress":"[::1]:52249","path":"/personsMiddleware","startTime":1699558778,"endTime":1699558778,"elapsedTime":0,"appVersion":"","request":{"id":1,"first_name":"first_name","last_name":"last_name"},"response":null,"status":"Ok","device":{"uuid":"","os":"","osVersion":""}}

我正在尝试获取请求的正文。 我试图获取上下文的主体(也许不理想,但我也没有成功)。 没有中间件,我可以毫无问题地获取请求的正文。

我想这可能是 config.toml 文件的内容,但我不确定内容应该是什么,它目前是一个空白文件。

go http middleware gorilla
1个回答
0
投票

r.Body
是一个
io.Reader
。从 io.Reader 读取一次后,就不可能再次读取它。没有一种内置方法可以简单地“重置”身体(据我所知)。

所以你需要做类似的事情

body, err := io.ReadAll(r.Body)
var requestBody RequestBody
err := json.Unmarshal(body, &requestBody)
// Replace the body with a new reader after reading from the original
r.Body = io.NopCloser(bytes.NewBuffer(body))
© www.soinside.com 2019 - 2024. All rights reserved.