Soy bastante nuevo en Go y todavía no lo entiendo todo. En muchos de los lenguajes modernos Node.js, Angular, jQuery, PHP, puede hacer una solicitud GET con parámetros de cadena de consulta adicionales.
Hacer esto en Go no es tan simple como parece, y todavía no puedo resolverlo. Realmente no quiero tener que concatenar una cadena para cada una de las solicitudes que quiero hacer.
Aquí está el script de muestra:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
client := &http.Client{}
req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular", nil)
req.Header.Add("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Errored when sending request to the server")
return
}
defer resp.Body.Close()
resp_body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(resp.Status)
fmt.Println(string(resp_body))
}
En este ejemplo, puede ver que hay una URL, que requiere una variable GET de api_key con su clave api como valor. El problema es que esto se codifica de forma rígida en forma de:
req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular?api_key=mySuperAwesomeApiKey", nil)
¿Hay alguna forma de construir esta cadena de consulta de forma dinámica? Por el momento, necesitaré ensamblar la URL antes de este paso para obtener una respuesta válida.
url.Values
elEncode
método de. También puede utilizarURL.String
para crear la URL completa.Respuestas:
Como mencionó un comentarista, puede obtener
Values
de lonet/url
que tiene unEncode
método. Podrías hacer algo como esto (req.URL.Query()
devuelve el existenteurl.Values
)package main import ( "fmt" "log" "net/http" "os" ) func main() { req, err := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular", nil) if err != nil { log.Print(err) os.Exit(1) } q := req.URL.Query() q.Add("api_key", "key_from_environment_or_flag") q.Add("another_thing", "foo & bar") req.URL.RawQuery = q.Encode() fmt.Println(req.URL.String()) // Output: // http://api.themoviedb.org/3/tv/popular?another_thing=foo+%26+bar&api_key=key_from_environment_or_flag }
http://play.golang.org/p/L5XCrw9VIG
fuente
Encode()
método.url.Parse("https://something.com/")
lugar, puede usar o incluso crear un objeto URL directamente.Úselo
r.URL.Query()
cuando agregue a una consulta existente, si está creando un nuevo conjunto de parámetros, use laurl.Values
estructura asípackage main import ( "fmt" "log" "net/http" "net/url" "os" ) func main() { req, err := http.NewRequest("GET","http://api.themoviedb.org/3/tv/popular", nil) if err != nil { log.Print(err) os.Exit(1) } // if you appending to existing query this works fine q := req.URL.Query() q.Add("api_key", "key_from_environment_or_flag") q.Add("another_thing", "foo & bar") // or you can create new url.Values struct and encode that like so q := url.Values{} q.Add("api_key", "key_from_environment_or_flag") q.Add("another_thing", "foo & bar") req.URL.RawQuery = q.Encode() fmt.Println(req.URL.String()) // Output: // http://api.themoviedb.org/3/tv/popularanother_thing=foo+%26+bar&api_key=key_from_environment_or_flag }
fuente
Usar
NewRequest
solo para crear una URL es una exageración. Usa elnet/url
paquete:package main import ( "fmt" "net/url" ) func main() { base, err := url.Parse("http://www.example.com") if err != nil { return } // Path params base.Path += "this will get automatically encoded" // Query params params := url.Values{} params.Add("q", "this will get encoded as well") base.RawQuery = params.Encode() fmt.Printf("Encoded URL is %q\n", base.String()) }
Zona de juegos: https://play.golang.org/p/YCTvdluws-r
fuente