DevGang
Авторизоваться

Golang: Работы с HTTP запросами часть 2

В предыдущей статье мы рассмотрели как отправлять GET запросы и работать с данными в JSON формате. Но что делать, если мы хотим передавать значения формы? Давайте рассмотрим остальные возможности Go для работы с HTTP запросами.

Для отправки данных в виде формы у нас есть удобная функция http.PostForm. Эта функция принимает два параметра url и url.Values из пакета net/url.

url.Values - это настраиваемый тип, который на самом деле представляет из себя map[string][]string структуру. То есть - это объект, который содержит ключи в виде строк и каждый ключ может содержать несколько строковых значений ([]string). В запросе формы вы можете отправить несколько значений по одному имени поля. Вот почему это фрагмент строки, а не только ключ к значению сопоставления.

Вот пример фрагмента кода:

func MakeRequest() {

	formData := url.Values{
		"name": {"masnun"},
	}

	resp, err := http.PostForm("https://httpbin.org/post", formData)
	if err != nil {
		log.Fatalln(err)
	}

	var result map[string]interface{}

	json.NewDecoder(resp.Body).Decode(&result)

	log.Println(result["form"])
}

Чтобы получить наши значения, мы должны для начала считать его из переменой result и обратиться к нему по ключу.

Кастомный Clients/Requests

Функции http.Get, http.Post или http.PostForm используют заранее созданный для нас стандартный клиент. Но теперь мы увидим, как мы можем инициализировать наш собственный экземпляр Client и использовать его, чтобы сделать новый объект Request. Давайте сначала посмотрим, как мы можем создавать экземпляр объекта Client и выполнять же запросы, которые мы делали ранее.

Ниже приведен краткий пример:

func MakeRequest() {

	client := http.Client{}
	request, err := http.NewRequest("GET", "https://httpbin.org/get", nil)
	if err != nil {
		log.Fatalln(err)
	}

	resp, err := client.Do(request)
	if err != nil {
		log.Fatalln(err)
	}

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	log.Println(result)
}

Как вы можете видеть, мы просто берем новый экземпляр http.Client, а затем создаем новый запрос, вызывая функцию http.NewRequest. Он принимает метод запроса, url и тело запроса. В нашем случае это простой GET запрос, поэтому третьим параметром мы передаем значение nil. Затем мы вызываем метод Do у нашего модуля Client и анализируем тело ответа. Вот и все: создайте клиент, создайте запрос, а затем позвольте клиенту выполнить запрос. Интересно, что у клиента также есть удобные методы, такие как Get, Post, PostForm - поэтому мы можем напрямую их использовать. Это то, что на самом деле делают http.Get, http.Post, http.PostForm и другие функции модуля http. Они вызывают эти методы в DefaultClient, который уже создан заранее. Фактически, мы могли просто сделать:

func MakeRequest() {

	client := http.Client{}
	resp, err := client.Get("https://httpbin.org/get")
	if err != nil {
		log.Fatalln(err)
	}

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	log.Println(result)
}

И это сработает аналогично предыдущему примеру. Теперь вы можете спросить: почему бы просто не использовать DefaultClient, зачем создавать собственный экземпляр клиента и какая в этом польза?

Если мы посмотрим на определение структуры http.Client, оно будет иметь следующие поля:

type Client struct {
	Transport RoundTripper
	CheckRedirect func(req *Request, via []*Request) error
	Jar CookieJar
	Timeout time.Duration
}

Если мы хотим, мы можем установить свою собственную реализацию транспорта, мы можем контролировать, как обрабатывается перенаправление, передать cookie для сохранения в файл и передать их в следующий запрос или просто установить тайм-аут. Роль тайм-аута часто очень важна при создании HTTP-запросов. DefaultClient не устанавливает тайм-аут по умолчанию. Поэтому, если вредоносная служба хочет, она может заблокировать ваши запросы (и ваши goroutines) на неопределенный срок, вызывая хаос в вашем приложении. Настройка клиента дает нам больший контроль над отправкой запросов.

#Golang
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться