Quiero realizar una solicitud POST a una API que envíe mis datos como un application/x-www-form-urlencodedtipo de contenido. Debido al hecho de que necesito administrar los encabezados de la solicitud, estoy usando el http.NewRequest(method, urlStr string, body io.Reader)método para crear una solicitud. Para esta solicitud POST, agrego mi consulta de datos a la URL y dejo el cuerpo vacío, algo como esto:
package main
import (
"bytes"
"fmt"
"net/http"
"net/url"
"strconv"
)
func main() {
apiUrl := "https://api.com"
resource := "/user/"
data := url.Values{}
data.Set("name", "foo")
data.Add("surname", "bar")
u, _ := url.ParseRequestURI(apiUrl)
u.Path = resource
u.RawQuery = data.Encode()
urlStr := fmt.Sprintf("%v", u) // "https://api.com/user/?name=foo&surname=bar"
client := &http.Client{}
r, _ := http.NewRequest("POST", urlStr, nil)
r.Header.Add("Authorization", "auth_token=\"XXXXXXX\"")
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
resp, _ := client.Do(r)
fmt.Println(resp.Status)
}
Como respondo, siempre obtengo un 400 BAD REQUEST. Creo que el problema se basa en mi solicitud y la API no comprende qué carga útil estoy publicando. Sin Request.ParseFormembargo, soy consciente de métodos como , no estoy seguro de cómo usarlo en este contexto. Tal vez me falte un encabezado adicional, tal vez ¿hay una mejor manera de enviar la carga útil como un application/jsontipo usando el bodyparámetro?

bdadovar b bytes.BufferContent-Lenghtencabezado, comohttp.NewRequestya lo hace.strings.NewReader(data.Encode())(más eficiente) en lugar debytes.NewBufferString(data.Encode()). En func NewReader (s string) * Reader , dice "NewReader devuelve una nueva lectura de Reader de s. Es similar a bytes.NewBufferString pero más eficiente y de solo lectura".data.Setdebe usarse para ambosnameysurname, en lugar dedata.Add. Establece el valor de la clave, en lugar de agregar otro valor a la misma clave, como lodata.Addhace.Addtambién funciona, pero no es necesarioappend(v[key], value)vaciar el segmento.