Номера строк и файлы, упомянутые в этом ответе, были записаны на дату ответа и не гарантируют вечной правильности.
Из dghubble's go -twitter search. go, строка 62, вызываемая функция client.Search.Tweets()
:
resp, err := s.sling.New().Get("tweets.json").QueryStruct(params).Receive(search, apiError)
Обратите внимание, что он использует пакет sling
для создания и отправки http-запроса, а также для получения и анализа http (JSON) ответ. Пакет sling
, к которому он относится, можно найти здесь .
В частности, обратите внимание на строп. go. В строке 366 комментарий гласит: «Receive - это сокращение для вызова Request и Do».
Функция Request()
, найденная в строке 280
, просто создает *http.Request
из объекта Sling
свойства. Он возвращает указанный запрос, а также ошибку (подпись func (s *Sling) Request() (*http.Request, error)
)
Функция Do()
является критической частью. Он выполняет HTTP-запрос, переданный в качестве первого аргумента, пытается проанализировать ответ (JSON) во втором предоставленном аргументе (интерфейс {}, который должен указывать на объект, на который должен быть проанализирован ответ), и одновременно пытается для анализа ошибок в третьем предоставленном аргументе. После всего этого он закрывает тело ответа. В частности, обратите внимание на строки 385 и 386:
// when err is nil, resp contains a non-nil resp.Body which must be closed
defer resp.Body.Close()
Другими словами, тело ответа закрывается еще до того, как оно дойдет до go -twitter Tweets()
scope, так что вы точно не сможете прочитать тело на своей стороне. В конце концов, одна из задач этих библиотек - избавить вас от хлопот, связанных с , имеющим для чтения и анализа тел ответов и т.п.
В общем, вы должны иметь возможность получать информацию вам нужно использовать предоставленные пакеты. В частности, функция Tweets()
имеет следующую сигнатуру: func (s *SearchService) Tweets(params *SearchTweetParams) (*Search, *http.Response, error)
. Обратите внимание, что первое возвращаемое значение имеет тип *Search
. Это объект, читаемый из Receive()
, и, в свою очередь, функция Do()
. Он должен содержать всю информацию из тела *http.Response
до его закрытия:
search , resp, err := client.Search.Tweets(&twitter.SearchTweetParams{
Query: "elon",
Count: 50,
})
Объект search
имеет тип *Search
, определение которого можно найти здесь . Он включает в себя набор статусов (Tweet
структур), а также некоторые метаданные. Вы также можете найти полезным определение структуры Tweet
, найденное здесь .
Наконец, если по какой-то причине вам действительно нужно иметь возможность самостоятельно обрабатывать тело запроса, вы приходится выполнять запрос с нуля, что в любом случае в большинстве случаев сводит на нет цели библиотек go-twitter
и sling
. Вы можете в некоторой степени использовать sling
для создания запроса, но это некрасиво (и на самом деле, вероятно, было бы проще создать запрос с нуля). Тем не менее, вот (непроверенный) пример кода, написанного со ссылкой на ссылки, ранее упомянутые в этом сообщении, а также этот :
func MyTweetsFunc(httpClient *http.Client, requestBuilder *sling.Sling, params *twitter.SearchTweetParams)
{
// Use sling's Request() to construct the request, just as Receive() does
req, err := requestBuilder.New().Get("tweets.json").QueryStruct(params).Request()
if err != nil {
// handle the error
}
// Get the response through the httpClient, since a sling client would parse and close the body automatically.
resp, err := httpClient.Do(req)
if err != nil {
// handle the error
}
// Now you can do whatever you want with resp, which is simply an *http.Response. Its body is open for reading.
}
И requestBuilder
может быть построено так:
const twitterAPI = "https://api.twitter.com/1.1/"
requestBuilder := sling.New().Client(httpClient).Base(twitterAPI)
Где httpClient
- это клиент, которому вы обычно переходите twitter.NewClient()