# #go #go-gin
Вопрос:
Я только вчера взял Go, и мне было интересно, как я могу сделать HTTP-запрос и вернуть результат этого запроса с помощью моего API, созданного с помощью Gin.
Это код конечной точки, которая возвращает результат другого запроса
func ProvideAccessToken(c *gin.Context) {
body := bindings.RequestAccessTokenBody{}
err := c.ShouldBind(amp;body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
log.Println(err)
return
}
if body.Code == "" || body.GrantType == "" || body.RedirectURI == "" {
c.String(http.StatusBadRequest, "Bad Request")
return
}
res, err := helpers.ExchangeCodeForToken(body.GrantType, body.RedirectURI, body.Code)
if err != nil {
c.JSON(res.StatusCode, gin.H{"error": err.Error()})
return
}
defer res.Body.Close()
c.Header("Content-Type", "application/json")
c.JSON(200, res.Body)
}
Это функция, которая выполняет HTTP-запрос
func ExchangeCodeForToken(grantType string, redirectUri string, code string) (*http.Response, error) {
authToken := "Basic " encodeClientSecretAndId()
body := url.Values{}
body.Set("grant_type", grantType)
body.Set("redirect_uri", redirectUri)
body.Set("code", code)
encodedBody := body.Encode()
client := amp;http.Client{}
r, _ := http.NewRequest(http.MethodPost, tokenUrl, strings.NewReader(encodedBody))
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
r.Header.Add("Authorization", authToken)
res, err := client.Do(r)
return res, err
}
Когда я использую почтальона для запроса, ответ-это просто пустой json, вот так {}
.
Когда измените конец моей ProvideAccessToken
функции на
defer res.Body.Close()
respbody, err := ioutil.ReadAll(res.Body)
if err != nil {
c.JSON(res.StatusCode, gin.H{"error": err.Error()})
return
}
c.Header("Content-Type", "application/json")
c.JSON(200, string(respbody))
Я получаю это в результате "{"error":"invalid_grant","error_description":"Authorization code expired"}"
, что правильно, но у него странное форматирование. Я просто хочу вернуть именно то, что возвращает другой API.
Ответ №1:
Первая версия программы кодирует значение тела ответа как JSON. Ответ {}, потому что в теле ответа нет экспортированных полей. Это не то, чего ты хочешь.
Вторая версия программы кодирует ответ JSON как JSON. Странное форматирование — это экранирование "
в исходном JSON.
Запишите данные как есть в ответ. Вот модификация второй версии программы:
defer res.Body.Close()
respbody, err := ioutil.ReadAll(res.Body)
if err != nil {
c.JSON(res.StatusCode, gin.H{"error": err.Error()})
return
}
c.Data(200, "application/json", respbody) // <-- note this line
Вы также можете копировать из одного ответа в другой:
defer res.Body.Close()
c.DataFromReader(200, res.ContentLength, "application/json", res.Body, nil)