Eu sou muito novo em Go e não entendo muito bem tudo ainda. Em muitas das linguagens modernas Node.js, Angular, jQuery, PHP, você pode fazer uma solicitação GET com parâmetros de string de consulta adicionais.
Fazer isso no Go não é tão simples quanto parece, e eu realmente não consigo descobrir ainda. Eu realmente não quero ter que concatenar uma string para cada uma das solicitações que desejo fazer.
Aqui está o script de exemplo:
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))
}
Neste exemplo, você pode ver que há um URL, que requer uma variável GET de api_key com sua chave de API como o valor. O problema é que isso se torna codificado na forma de:
req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular?api_key=mySuperAwesomeApiKey", nil)
Existe uma maneira de construir essa string de consulta dinamicamente ?? No momento, precisarei montar a URL antes desta etapa para obter uma resposta válida.
url.Values
oEncode
método de. Você também pode usarURL.String
para construir a URL inteira.Respostas:
Como um comentador mencionado, você pode obter
Values
denet/url
qual tem umEncode
método. Você poderia fazer algo assim (req.URL.Query()
retorna o 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
fonte
Encode()
método.url.Parse("https://something.com/")
vez disso ou até mesmo criar um objeto URL diretamente.Use
r.URL.Query()
quando você anexar a uma consulta existente, se você estiver construindo um novo conjunto de parâmetros, use aurl.Values
estrutura assimpackage 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 }
fonte
Usar
NewRequest
apenas para criar um URL é um exagero. Use onet/url
pacote: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()) }
Playground: https://play.golang.org/p/YCTvdluws-r
fonte