Go Resty - библиотека языка Go для создания клиентов RESTful API. С Go Resty разработчики могут быстро и эффективно создавать надежных клиентов RESTful API. Эта глава представляет, как быстро начать работу с Go Resty.

Установка

require github.com/go-resty/resty/v2 v2.7.0

или

go get github.com/go-resty/resty/v2

Пример использования Resty

Следующие примеры помогут вам использовать библиотеку resty максимально удобным образом.

// Импортируйте resty в ваш код и обратитесь к нему как `resty`.
import "github.com/go-resty/resty/v2"

Простой GET-запрос

// Создайте клиент Resty
client := resty.New()

resp, err := client.R().
    EnableTrace().
    Get("https://httpbin.org/get")

// Изучите объект ответа
fmt.Println("Информация о ответе:")
fmt.Println("  Ошибка  :", err)
fmt.Println("  Код статуса:", resp.StatusCode())
fmt.Println("  Статус  :", resp.Status())
fmt.Println("  Протокол:", resp.Proto())
fmt.Println("  Время  :", resp.Time())
fmt.Println("  Получено в:", resp.ReceivedAt())
(fmt.Println("  Содержимое  :\n", resp)
fmt.Println()

// Изучите информацию о трассировке
fmt.Println("Информация о трассировке запроса:")
ti := resp.Request.TraceInfo()
fmt.Println("  Поиск DNS      :", ti.DNSLookup)
fmt.Println("  Время соединения    :", ti.ConnTime)
fmt.Println("  Время подключения TCP:", ti.TCPConnTime)
fmt.Println("  Рукопожатие TLS   :", ti.TLSHandshake)
fmt.Println("  Время сервера     :", ti.ServerTime)
fmt.Println("  Время ответа   :", ti.ResponseTime)
fmt.Println("  Общее время      :", ti.TotalTime)
fmt.Println("  Переиспользование соединения  :", ti.IsConnReused)
fmt.Println("  Соединение было бездействующим   :", ti.IsConnWasIdle)
fmt.Println("  Время бездействия соединения  :", ti.ConnIdleTime)
fmt.Println("  Попытка запроса :", ti.RequestAttempt)
fmt.Println("  Удаленный адрес  :", ti.RemoteAddr.String())
Вывод
Информация о ответе:
  Ошибка  : 
  Код статуса: 200
  Статус  : 200 OK
  Протокол: HTTP/2.0
  Время  : 457.034718ms
  Получено в: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
  Содержимое  :
  {
    "args": {},
    "headers": {
      "Accept-Encoding": "gzip",
      "Host": "httpbin.org",
      "User-Agent": "go-resty/2.4.0 (https://github.com/go-resty/resty)",
      "X-Amzn-Trace-Id": "Root=1-5f5ff031-000ff6292204aa6898e4de49"
    },
    "origin": "0.0.0.0",
    "url": "https://httpbin.org/get"
  }

Информация о трассировке запроса:
  Поиск DNS      : 4.074657ms
  Время соединения    : 381.709936ms
  Время подключения TCP: 77.428048ms
  Рукопожатие TLS   : 299.623597ms
  Время сервера     : 75.414703ms
  Время ответа   : 79.337µs
  Общее время      : 457.034718ms
  Переиспользование соединения  : false
  Соединение было бездействующим   : false
  Время бездействия соединения  : 0s
  Попытка запроса : 1
  Удаленный адрес  : 3.221.81.55:443

Сложный GET-запрос

// Создание клиента Resty
client := resty.New()

// Установка параметров запроса
resp, err := client.R().
      SetQueryParams(map[string]string{
          "page_no": "1",
          "limit": "20",
          "sort":"name",
          "order": "asc",
          "random":strconv.FormatInt(time.Now().Unix(), 10),
      }).
      SetHeader("Accept", "application/json").
      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
      Get("/search_result")


// Пример с использованием метода Request.SetQueryString
resp, err := client.R().
      SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=купить больше").
      SetHeader("Accept", "application/json").
      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
      Get("/show_product")


// При необходимости можно принудительно указать тип содержимого ответа, чтобы указать Resty на парсинг JSON-ответа в вашу структуру
resp, err := client.R().
      SetResult(result).
      ForceContentType("application/json").
      Get("v2/alpine/manifests/latest")

Различные примеры POST-запросов

// Создание клиента Resty
client := resty.New()

// Отправка JSON-строки
// Если уровень настроек клиента уже установлен, не нужно устанавливать тип содержимого
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      SetResult(&AuthSuccess{}).    // или SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// Отправка массива []byte
// Если уровень настроек клиента уже установлен, не нужно устанавливать тип содержимого
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
      SetResult(&AuthSuccess{}).    // или SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// Отправка структуры, по умолчанию используется тип содержимого JSON, не нужно устанавливать
resp, err := client.R().
      SetBody(User{Username: "testuser", Password: "testpass"}).
      SetResult(&AuthSuccess{}).    // или SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // или SetError(AuthError{}).
      Post("https://myapp.com/login")

// Отправка карты, по умолчанию используется тип содержимого JSON, не нужно устанавливать
resp, err := client.R().
      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
      SetResult(&AuthSuccess{}).    // или SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // или SetError(AuthError{}).
      Post("https://myapp.com/login")

// Загрузка файла как массива байтов. Пример: Загрузка файла в Dropbox
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")

// Обратите внимание, что мы не устанавливаем заголовок типа содержимого, потому что go-resty автоматически определит Content-Type
resp, err := client.R().
      SetBody(fileBytes).
      SetContentLength(true).          // Dropbox требует это значение
      SetAuthToken("").
      SetError(&DropboxError{}).       // или SetError(DropboxError{}).
      Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // DropBox также поддерживает загрузку методом PUT

// Примечание: Если заголовок типа содержимого не установлен, resty определит Content-Type тела запроса
//   * Для типов данных struct и map по умолчанию устанавливается 'application/json'
//   * Затем идет обычный текстовый тип содержимого

Запрос на PUT

Вы можете использовать различные комбинации вызова метода PUT, так же как показано для POST.

// Примечание: Это пример использования метода PUT, для более подробных комбинаций обратитесь к POST

// Создание клиента Resty
client := resty.New()

// Отправка запроса с типом содержимого JSON
// Если есть настройки на уровне клиента, токен аутентификации может быть опущен
resp, err := client.R().
      SetBody(Article{
        Title: "go-resty",
        Content: "Это содержимое моей статьи, о да!",
        Author: "Jeevanandam M",
        Tags: []string{"статья", "пример", "resty"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Или SetError(Error{}).
      Put("https://myapp.com/article/1234")

Запрос на PATCH

Вы можете использовать различные комбинации вызова метода PATCH, так же как показано для POST.

// Примечание: Это пример использования метода PATCH, для более подробных комбинаций обратитесь к POST

// Создание клиента Resty
client := resty.New()

// Отправка запроса с типом содержимого JSON
// Если есть настройки на уровне клиента, токен аутентификации может быть опущен
resp, err := client.R().
      SetBody(Article{
        Tags: []string{"новый тег 1", "новый тег 2"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Или SetError(Error{}).
      Patch("https://myapp.com/articles/1234")

DELETE, HEAD, OPTIONS Запрос

// Создание клиента Resty
client := resty.New()

// Удаление статьи
// Если есть настройки на уровне клиента, токен аутентификации может быть опущен
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Или SetError(Error{}).
      Delete("https://myapp.com/articles/1234")

// Удаление нескольких статей с использованием JSON-строки в качестве содержимого
// Если есть настройки на уровне клиента, токен аутентификации может быть опущен
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Или SetError(Error{}).
      SetHeader("Content-Type", "application/json").
      SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
      Delete("https://myapp.com/articles")

// Получение информации заголовка ресурса
// Если есть настройки на уровне клиента, токен аутентификации может быть опущен
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Head("https://myapp.com/videos/hi-res-video")

// Получение информации об опциях ресурса
// Если есть настройки на уровне клиента, токен аутентификации может быть опущен
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Options("https://myapp.com/servers/nyc-dc-01")

Настройка операций сериализации/десериализации JSON и XML

Пользователи могут зарегистрировать выбранные ими библиотеки JSON/XML с Resty, или написать собственные библиотеки. По умолчанию Resty регистрирует стандартные библиотеки encoding/json и encoding/xml.

// Пример регистрации json-iterator
import jsoniter "github.com/json-iterator/go"

json := jsoniter.ConfigCompatibleWithStandardLibrary

client := resty.New().
    SetJSONMarshaler(json.Marshal).
    SetJSONUnmarshaler(json.Unmarshal)

// Аналогично, пользователи могут настроить XML следующим образом -
client.SetXMLMarshaler(xml.Marshal).
    SetXMLUnmarshaler(xml.Unmarshal)