Je suis assez nouveau pour Go et je ne comprends pas encore tout. Dans la plupart des langages modernes Node.js, Angular, jQuery, PHP, vous pouvez effectuer une requête GET avec des paramètres de chaîne de requête supplémentaires.
Faire cela dans Go n'est pas aussi simple qu'il y paraît, et je ne le comprends pas encore. Je ne veux vraiment pas avoir à concaténer une chaîne pour chacune des demandes que je veux faire.
Voici l'exemple de script:
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))
}
Dans cet exemple, vous pouvez voir qu'il existe une URL qui requiert une variable GET de api_key avec votre clé api comme valeur. Le problème est que cela devient codé en dur sous la forme de:
req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular?api_key=mySuperAwesomeApiKey", nil)
Est-il possible de construire cette chaîne de requête de manière dynamique? Pour le moment, je devrai assembler l'URL avant cette étape afin d'obtenir une réponse valide.
Comme un commentateur l'a mentionné, vous pouvez obtenir Values
à partir de net/url
, Qui a une méthode Encode
. Vous pouvez faire quelque chose comme ceci (req.URL.Query()
renvoie le url.Values
Existant)
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
}
Utilisez r.URL.Query()
lorsque vous ajoutez une requête existante, si vous construisez un nouvel ensemble de paramètres, utilisez la méthode url.Values
struct comme si
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
}
Utiliser NewRequest
simplement pour créer une URL est une overkill. Utilisez le net/url
paquet:
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())
}
Aire de jeu: https://play.golang.org/p/YCTvdluws-r