I'm new to Go and Gin, and am having trouble printing out the full request body.
I want to be able to read the request body from third party POST, but I'm getting empty request body
curl -u dumbuser:dumbuserpassword -H "Content-Type: application/json" -X POST --data '{"events": "3"}' http://localhost:8080/events
My entire code is as below. Any pointer is appreciated!
package main
import (
"net/http"
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
authorized := router.Group("/", gin.BasicAuth(gin.Accounts{
"dumbuser": "dumbuserpassword",
}))
authorized.POST("/events", events)
router.Run(":8080")
}
func events(c *gin.Context) {
fmt.Printf("%s", c.Request.Body)
c.JSON(http.StatusOK, c)
}
The problem here is that you're printing out the string value of c.Request.Body
, which is of interface type ReadCloser
.
What you can do to satisfy yourself that it does in fact contain the body you want is to read the value out of c.Request.Body
to a string, and then print that out. This is for your learning process only!
Learning code:
func events(c *gin.Context) {
x, _ := ioutil.ReadAll(c.Request.Body)
fmt.Printf("%s", string(x))
c.JSON(http.StatusOK, c)
}
However, this is not the way you should access the body of the request. Let gin do the parsing of the body for you, by using a binding.
More correct code:
type E struct {
Events string
}
func events(c *gin.Context) {
data := &E{}
c.Bind(data)
fmt.Println(data)
c.JSON(http.StatusOK, c)
}
This is a more correct way to access the data in the body, since it will be already parsed out for you. Note that if you read the body first, as we did above in the learning step, the c.Request.Body
will have been emptied, and so there will be nothing left in the body for Gin to read.
Broken code:
func events(c *gin.Context) {
x, _ := ioutil.ReadAll(c.Request.Body)
fmt.Printf("%s", string(x))
data := &E{}
c.Bind(data) // data is left unchanged because c.Request.Body has been used up.
fmt.Println(data)
c.JSON(http.StatusOK, c)
}
You're probably also curious why the JSON returned from this endpoint shows and empty Request.Body
. This is for the same reason. The JSON Marshalling method cannot serialize a ReadCloser
, and so it shows up as empty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With