Reputation: 3928
I have the following code:
package main
import (
"bytes"
"fmt"
"net/http"
)
func main() {
var jsonStr = []byte(`{"title":"Buy cheese and bread for breakfast."}`)
req, err := http.NewRequest("POST", "/", bytes.NewBuffer(jsonStr))
if err != nil {
panic(err)
}
req.Header.Set("X-Custom-Header", "myvalue")
req.Header.Set("Content-Type", "application/json")
req.ParseForm()
fmt.Printf("%v:%v", "title", req.Form.Get("title"))
}
I am unable to extract the "title" param and not sure why.
Upvotes: 1
Views: 4388
Reputation: 11532
The 3rd argument of http.NewRequest
is the http payload.
In your case, payload type is application/json
. It's need to be treated as json, only then you'll be able to get certain value from the it. In this case, we just cannot use the same technique like on getting value from query string or form data.
So just unmarshal the jsonStr
data into map or struct.
res := make(map[string]interface{})
err := json.Unmarshal(jsonStr, &res)
if err != nil {
panic(err)
}
fmt.Printf("%#v \n", res["title"])
To be honest I'm quite confused with your question, why you need to get the payload from http client request.
If what you want is actually how to get the payload from the web server end, you can get it by decoding the request body. Example:
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
payload := make(map[string]interface{})
err := json.NewDecoder(r.Body).Decode(&payload)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
title := payload["title"].(string)
w.Write([]byte(title))
})
Curl example (based on your code):
curl -d '{"title":"Buy cheese and bread for breakfast."}' \
-H "Content-Type: application/json" \
-X POST http://localhost:9000
Output:
Buy cheese and bread for breakfast.
Upvotes: 2
Reputation: 441
As noted in the GoDoc for the http.Request.ParseForm
method, the type of the body must be application/x-www-form-urlencoded
, not JSON like your current example:
For other HTTP methods, or when the Content-Type is not application/x-www-form-urlencoded, the request Body is not read, and r.PostForm is initialized to a non-nil, empty value.
Here is an updated example of your code using a form body, which gives the intended result: https://play.golang.org/p/Zrw05T2Zb5Z
If you want to extract values from a JSON body, that can be done using a method such as json.Unmarshal
, however a JSON body doesn't represent a form.
Upvotes: 3
Reputation: 16304
Because your request isn't a form. It doesn't have any GET parameters, and it isn't form-encoded data.
For other HTTP methods, or when the Content-Type is not application/x-www-form-urlencoded, the request Body is not read, and r.PostForm is initialized to a non-nil, empty value.
[ https://golang.org/pkg/net/http/#Request.ParseForm ]
You're free to parse the body of the request as application/json
, but that isn't the same as form data.
Upvotes: 1