Search code examples
jsongocurlgo-chi

trying to read JSON from a cURL gives "<nil>"


I'm trying to CURL an endpoint using go-chi and I'm having trouble getting the JSON from the curl, my code looks like this

type Message struct {
    From    string `json:"From"`
    Message string `json:"Message"`

}


//in main()
router.Post("/newMessage", func(w http.ResponseWriter, r *http.Request ){          

        var msgStruct Message
    var decoded = json.NewDecoder(r.Body).Decode(&msgStruct)
    fmt.Println(decoded)
        fmt.Println(r.Body)
    p, _ := io.ReadAll(r.Body); fmt.Printf("%s\n", p)

    })

My curl curl -X POST http://localhost:8000/newMessage -d '{"From": "me", "Message": "msg"}' -H "Content-Type: application/json"

And what is getting logged to the console

&{0xc000134150 <nil> <nil> false true {0 0} true false false 0x656820}
<nil>
// nothing get printed from the io.ReadAll

I'm new to GO so I've not had much luck debugging this. I've tried to follow instructions online but unfortunately not many howtos deal with POSTs and I've found none that use curl with go.

Thanks in advanced


Solution

  • There are a few mistakes here.

    • r.Body is a stream, so after it's consumed it cannot be read again unless you buffer or reset it.
    • json.NewDecoder(r.Body).Decode the return value of Decode is an error, not the decoded data itself.

    Let's fix it:

    type Message struct {
        From    string `json:"From"`
        Message string `json:"Message"`
    }
    
    router.Post("/newMessage", func(w http.ResponseWriter, r *http.Request) {
            var msgStruct Message
    
            // Decode JSON directly into the struct
            if err := json.NewDecoder(r.Body).Decode(&msgStruct); err != nil {
                http.Error(w, "Failed to decode JSON", http.StatusBadRequest)
                fmt.Println("Error decoding JSON:", err)
                return
            }
    
            // Log the received message
            fmt.Printf("Received Message: %+v\n", msgStruct)
    })