GET 요청을 수행하고 Querystring을 작성하십시오.


85

나는 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을 조합해야합니다.


1
그렇다면 문자열을 연결하는 데 어떤 문제가 있습니까?
Salvador Dali

4
나는 아무것도 생각하지 않는다. 그러나 그것은 정말로 우아한 해결책이 아니다. 단지 Go에서 일을하는 더 좋은 방법이 있다고 생각했다. 동작 변경, 방법, 그리고 모든 것을 함께 묶어야합니다.
Rudi Strydom

2
url.ValuesEncode방법을 사용할 수 있습니다 . URL.String전체 URL을 작성하는 데 사용할 수도 있습니다 .
Dave C

답변:


208

주석 기 언급했듯이 당신이 얻을 수 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


1
정말 감사합니다! 그것이 바로 제가 찾던 것입니다!
Rudi Strydom 2015-06-05

테스트에도 좋습니다!
Kyle Chadha

원하는 순서로 쿼리 문자열 매개 변수를 만드는 솔루션이 있습니까? 키는 Encode()방법 으로 정렬됩니다 .
artificerpi

1
@artificerpi 어떤 이유로 든 중요하다면 Encode 메서드 golang.org/src/net/url/url.go?s=24222:24253#L845 내부에서 수행하는 작업을 다시 구현할 수 있지만 왜 중요한지 궁금합니다.
jcbwlkr

3
아무것도하지 않는다면 NewRequest를 사용할 필요가 없습니다. 당신은 사용할 수 있습니다 url.Parse("https://something.com/")대신하거나 직접 URL 객체를 생성합니다.
리처드

34

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
}

11

사용하여 NewRequestURL을 생성하는 단지 것은 과잉이다. 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


가장 간단한 대답과 완벽하게 작동했습니다. 감사합니다
Jake Boomgaarden
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.