Я новичок в 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))
}
В этом примере вы можете увидеть, что есть URL-адрес, для которого требуется переменная GET api_key с вашим ключом api в качестве значения. Проблема в том, что это становится жестко закодированным в форме:
req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular?api_key=mySuperAwesomeApiKey", nil)
Есть ли способ динамически построить эту строку запроса? На данный момент мне нужно будет собрать URL-адрес до этого шага, чтобы получить действительный ответ.
url.Values
«SEncode
метод. Вы также можете использоватьURL.String
для создания всего 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 }
http://play.golang.org/p/L5XCrw9VIG
источник
Encode()
методам.url.Parse("https://something.com/")
вместо него или даже создать объект URL напрямую.Используйте
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()) }
Площадка: https://play.golang.org/p/YCTvdluws-r
источник