Go Resty

Go Resty é uma biblioteca de linguagem Go para construir clientes de API RESTful. Com Go Resty, os desenvolvedores podem construir clientes de API RESTful de forma mais rápida e eficiente. Este capítulo introduz como começar rapidamente com o Go Resty.

Instalação

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

ou

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

Exemplo Resty

Os exemplos a seguir irão ajudá-lo a usar a biblioteca resty o mais confortavelmente possível.

// Importe resty em seu código e faça referência a ele como `resty`.
import "github.com/go-resty/resty/v2"

Solicitação GET Simples

// Crie um cliente Resty
client := resty.New()

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

// Explore o objeto de resposta
fmt.Println("Informações da resposta:")
fmt.Println("  Erro          :", err)
fmt.Println("  Código de status:", resp.StatusCode())
fmt.Println("  Status        :", resp.Status())
fmt.Println("  Protocolo     :", resp.Proto())
fmt.Println("  Tempo         :", resp.Time())
fmt.Println("  Recebido em   :", resp.ReceivedAt())
fmt.Println("  Corpo         :\n", resp)
fmt.Println()

// Explore informações de rastreamento
fmt.Println("Informações de rastreamento da solicitação:")
ti := resp.Request.TraceInfo()
fmt.Println("  Pesquisa de DNS:", ti.DNSLookup)
fmt.Println("  Tempo de conexão:", ti.ConnTime)
fmt.Println("  Tempo de conexão TCP:", ti.TCPConnTime)
fmt.Println("  Aperto de mão TLS:", ti.TLSHandshake)
fmt.Println("  Tempo do servidor:", ti.ServerTime)
fmt.Println("  Tempo de resposta:", ti.ResponseTime)
fmt.Println("  Tempo total:", ti.TotalTime)
fmt.Println("  Conexão reutilizada:", ti.IsConnReused)
fmt.Println("  Conexão estava inativa:", ti.IsConnWasIdle)
fmt.Println("  Tempo inativo da conexão:", ti.ConnIdleTime)
fmt.Println("  Tentativa de solicitação:", ti.RequestAttempt)
fmt.Println("  Endereço remoto:", ti.RemoteAddr.String())
Saída
Informações da resposta:
  Erro          : 
  Código de status: 200
  Status        : 200 OK
  Protocolo     : HTTP/2.0
  Tempo         : 457,034718ms
  Recebido em   : 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
  Corpo         :
  {
    "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"
  }

Informações de rastreamento da solicitação:
  Pesquisa de DNS: 4,074657ms
  Tempo de conexão: 381,709936ms
  Tempo de conexão TCP: 77,428048ms
  Aperto de mão TLS: 299,623597ms
  Tempo do servidor: 75,414703ms
  Tempo de resposta: 79,337µs
  Tempo total: 457,034718ms
  Conexão reutilizada: falso
  Conexão estava inativa: falso
  Tempo inativo da conexão: 0s
  Tentativa de solicitação: 1
  Endereço remoto: 3.221.81.55:443

Pedido GET Complexo

// Criar um cliente Resty
client := resty.New()

// Definir parâmetros de consulta
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("/resultados_pesquisa")


// Exemplo usando o método Request.SetQueryString
resp, err := client.R().
      SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=comprar muito mais").
      SetHeader("Accept", "application/json").
      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
      Get("/mostrar_produto")


// Se necessário, forçar o tipo de conteúdo de resposta especificado para instruir o Resty a analisar a resposta JSON na sua estrutura
resp, err := client.R().
      SetResult(result).
      ForceContentType("application/json").
      Get("v2/alpine/manifests/latest")

Vários Exemplos de Pedido POST

// Criar um cliente Resty
client := resty.New()

// POST de uma string JSON
// Se as configurações em nível de cliente tiverem sido definidas, o tipo de conteúdo não precisa ser definido
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      SetResult(&AuthSuccess{}).    // ou SetResult(AuthSuccess{}).
      Post("https://meuapp.com/login")

// POST de uma matriz de bytes []
// Se as configurações em nível de cliente tiverem sido definidas, o tipo de conteúdo não precisa ser definido
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
      SetResult(&AuthSuccess{}).    // ou SetResult(AuthSuccess{}).
      Post("https://meuapp.com/login")

// POST de uma estrutura, padrão para o tipo de conteúdo JSON, não é necessário definir
resp, err := client.R().
      SetBody(User{Username: "testuser", Password: "testpass"}).
      SetResult(&AuthSuccess{}).    // ou SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // ou SetError(AuthError{}).
      Post("https://meuapp.com/login")

// POST de um mapa, padrão para o tipo de conteúdo JSON, não é necessário definir
resp, err := client.R().
      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
      SetResult(&AuthSuccess{}).    // ou SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // ou SetError(AuthError{}).
      Post("https://meuapp.com/login")

// Enviar arquivo como matriz de bytes em bruto. Exemplo: Enviar um arquivo para o Dropbox
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")

// Observação: não definimos o cabeçalho do tipo de conteúdo porque o go-resty detectará automaticamente o Content-Type
resp, err := client.R().
      SetBody(fileBytes).
      SetContentLength(true).          // O Dropbox requer esse valor
      SetAuthToken("").
      SetError(&DropboxError{}).       // ou SetError(DropboxError{}).
      Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // O DropBox também oferece suporte a uploads via método PUT

// Observação: Se o cabeçalho do tipo de conteúdo não for definido, o resty detectará o Content-Type do corpo da solicitação
//   * Para os tipos de dados de estrutura e mapa, o padrão é 'application/json'
//   * Depois é o tipo de conteúdo de texto normal

Pedido PUT

Você pode usar várias combinações da chamada do método PUT como demonstrado para POST.

// Nota: Este é um exemplo de uso do método PUT, para mais combinações, consulte POST

// Criar um cliente Resty
client := resty.New()

// Enviar solicitação com tipo de conteúdo JSON
// Se houver configurações no nível do cliente, o token de autenticação pode ser omitido, error
resp, err := client.R().
      SetBody(Article{
        Title: "go-resty",
        Content: "Este é o conteúdo do meu artigo, oh yeah!",
        Author: "Jeevanandam M",
        Tags: []string{"artigo", "exemplo", "resty"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Ou SetError(Error{}).
      Put("https://myapp.com/article/1234")

Pedido PATCH

Você pode usar várias combinações da chamada do método PATCH como demonstrado para POST.

// Nota: Este é um exemplo de uso do método PATCH, para mais combinações, consulte POST

// Criar um cliente Resty
client := resty.New()

// Enviar solicitação com tipo de conteúdo JSON
// Se houver configurações no nível do cliente, o token de autenticação pode ser omitido, error
resp, err := client.R().
      SetBody(Article{
        Tags: []string{"novo tag 1", "novo tag 2"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Ou SetError(Error{}).
      Patch("https://myapp.com/articles/1234")

Pedido DELETE, HEAD, OPTIONS

// Criar um cliente Resty
client := resty.New()

// Excluir um artigo
// Se houver configurações no nível do cliente, o token de autenticação pode ser omitido, error
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Ou SetError(Error{}).
      Delete("https://myapp.com/articles/1234")

// Excluir vários artigos com uma string JSON como payload/conteúdo
// Se houver configurações no nível do cliente, o token de autenticação pode ser omitido, error
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Ou SetError(Error{}).
      SetHeader("Content-Type", "application/json").
      SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
      Delete("https://myapp.com/articles")

// Obter as informações do cabeçalho de um recurso
// Se houver configurações no nível do cliente, o token de autenticação pode ser omitido
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Head("https://myapp.com/videos/hi-res-video")

// Obter as informações de opções de um recurso
// Se houver configurações no nível do cliente, o token de autenticação pode ser omitido
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Options("https://myapp.com/servers/nyc-dc-01")

Configurando Operações de Serialização/Deserialização JSON e XML

Os usuários podem registrar suas bibliotecas escolhidas de JSON/XML com resty, ou escrever suas próprias bibliotecas. Por padrão, resty registra as bibliotecas padrão encoding/json e encoding/xml.

// Exemplo de registro do json-iterator
import jsoniter "github.com/json-iterator/go"

json := jsoniter.ConfigCompatibleWithStandardLibrary

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

// Da mesma forma, os usuários podem configurar XML da seguinte forma -
client.SetXMLMarshaler(xml.Marshal).
    SetXMLUnmarshaler(xml.Unmarshal)