私はGoが初めてで、まだすべてを理解していません。 Node.js、Angular、jQuery、PHPなどの現代言語の多くでは、追加のクエリ文字列パラメーターを使用してGETリクエストを実行できます。
Goでこれを行うことは、見た目ほど簡単ではなく、まだ理解できていません。実行したいリクエストごとに文字列を連結する必要は本当にありません。
サンプルスクリプトを次に示します。
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))
}
この例では、値がapiキーのapi_keyのGET変数を必要とするURLがあることがわかります。問題は、これが次の形式でハードコーディングされることです。
req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular?api_key=mySuperAwesomeApiKey", nil)
このクエリ文字列を動的に作成する方法はありますか?現時点では、有効な応答を得るために、このステップの前にURLを組み立てる必要があります。
コメンターが述べたように、Values
メソッドを持つnet/url
からEncode
を取得できます。このようなことができます(req.URL.Query()
は既存のurl.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
}
既存のクエリに追加する場合はr.URL.Query()
を使用します。新しいパラメータセットを作成する場合は、url.Values
構造体を使用します
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
}
NewRequest
を使用してURLを作成するだけではやり過ぎです。 net/url
パッケージを使用します。
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())
}