Go Resty es una biblioteca del lenguaje Go para construir clientes de API RESTful. Con Go Resty, los desarrolladores pueden construir clientes de API RESTful de manera más rápida y eficiente. Este capítulo introduce cómo comenzar rápidamente con Go Resty.

Instalación

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

o

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

Ejemplo de Resty

Los siguientes ejemplos te ayudarán a utilizar la biblioteca resty de la forma más cómoda posible.

// Importa resty en tu código y haz referencia a él como `resty`.
import "github.com/go-resty/resty/v2"

Solicitud GET simple

// Crea un cliente Resty
cliente := resty.New()

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

// Explora el objeto de respuesta
fmt.Println("Información de la respuesta:")
fmt.Println("  Error      :", err)
fmt.Println("  Código de estado:", resp.StatusCode())
fmt.Println("  Estado     :", resp.Status())
fmt.Println("  Protocolo   :", resp.Proto())
fmt.Println("  Tiempo     :", resp.Time())
fmt.Println("  Recibido en:", resp.ReceivedAt())
fmt.Println("  Cuerpo     :\n", resp)
fmt.Println()

// Explora la información de seguimiento
fmt.Println("Información de seguimiento de la solicitud:")
ti := resp.Request.TraceInfo()
fmt.Println("  Búsqueda DNS      :", ti.DNSLookup)
fmt.Println("  Tiempo de conexión    :", ti.ConnTime)
fmt.Println("  Tiempo de conexión TCP:", ti.TCPConnTime)
fmt.Println("  Handshake TLS   :", ti.TLSHandshake)
fmt.Println("  Tiempo del servidor     :", ti.ServerTime)
fmt.Println("  Tiempo de respuesta   :", ti.ResponseTime)
fmt.Println("  Tiempo total      :", ti.TotalTime)
fmt.Println("  Se reutiliza la conexión  :", ti.IsConnReused)
fmt.Println("  La conexión estaba inactiva   :", ti.IsConnWasIdle)
fmt.Println("  Tiempo inactivo de la conexión  :", ti.ConnIdleTime)
fmt.Println("  Intento de solicitud  :", ti.RequestAttempt)
fmt.Println("  Dirección remota  :", ti.RemoteAddr.String())
Salida
Información de la respuesta:
  Error      : 
  Código de estado: 200
  Estado     : 200 OK
  Protocolo   : HTTP/2.0
  Tiempo     : 457.034718ms
  Recibido en: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
  Cuerpo     :
  {
    "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"
  }

Información de seguimiento de la solicitud:
  Búsqueda DNS      : 4.074657ms
  Tiempo de conexión    : 381.709936ms
  Tiempo de conexión TCP: 77.428048ms
  Handshake TLS   : 299.623597ms
  Tiempo del servidor     : 75.414703ms
  Tiempo de respuesta   : 79.337µs
  Tiempo total      : 457.034718ms
  Se reutiliza la conexión  : false
  La conexión estaba inactiva   : false
  Tiempo inactivo de la conexión  : 0s
  Intento de solicitud  : 1
  Dirección remota  : 3.221.81.55:443

Solicitud GET compleja

// Crear un cliente Resty
cliente := resty.New()

// Establecer parámetros de consulta
resp, err := cliente.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")


// Ejemplo usando el método Request.SetQueryString
resp, err := cliente.R().
      SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
      SetHeader("Accept", "application/json").
      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
      Get("/show_product")


// Si es necesario, forzar el tipo de contenido de respuesta especificado para indicar a Resty que analice la respuesta JSON en su estructura
resp, err := cliente.R().
      SetResult(result).
      ForceContentType("application/json").
      Get("v2/alpine/manifests/latest")

Varios ejemplos de solicitud POST

// Crear un cliente Resty
cliente := resty.New()

// POST de una cadena JSON
// Si se han establecido configuraciones a nivel de cliente, no es necesario establecer el tipo de contenido
resp, err := cliente.R().
      SetHeader("Content-Type", "application/json").
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      SetResult(&AuthSuccess{}).    // o SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// POST de una matriz []byte
// Si se han establecido configuraciones a nivel de cliente, no es necesario establecer el tipo de contenido
resp, err := cliente.R().
      SetHeader("Content-Type", "application/json").
      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
      SetResult(&AuthSuccess{}).    // o SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// POST de una estructura, por defecto el tipo de contenido es JSON, no es necesario establecerlo
resp, err := cliente.R().
      SetBody(User{Username: "testuser", Password: "testpass"}).
      SetResult(&AuthSuccess{}).    // o SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // o SetError(AuthError{}).
      Post("https://myapp.com/login")

// POST de un mapa, por defecto el tipo de contenido es JSON, no es necesario establecerlo
resp, err := cliente.R().
      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
      SetResult(&AuthSuccess{}).    // o SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // o SetError(AuthError{}).
      Post("https://myapp.com/login")

// Subir un archivo como una matriz de bytes brutos. Ejemplo: Subir un archivo a Dropbox
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")

// Tenga en cuenta que no establecemos el encabezado de tipo de contenido porque go-resty detectará automáticamente el Content-Type
resp, err := cliente.R().
      SetBody(fileBytes).
      SetContentLength(true).          // Dropbox requiere este valor
      SetAuthToken("").
      SetError(&DropboxError{}).       // o SetError(DropboxError{}).
      Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // Dropbox también admite subidas con el método PUT

// Nota: Si el encabezado de tipo de contenido no se establece, resty detectará el Content-Type del cuerpo de la solicitud
//   * Para estructuras y tipos de datos de mapa, el valor predeterminado es 'application/json'
//   * Luego es el tipo de contenido de texto normal

Solicitud PUT

Puede utilizar varias combinaciones de la llamada del método PUT tal como se muestra para POST.

// Nota: Este es un ejemplo de uso del método PUT, para más combinaciones consulte POST

// Crear un cliente Resty
cliente := resty.New()

// Enviar solicitud con tipo de contenido JSON
// Si hay ajustes a nivel de cliente, se puede omitir el token de autenticación, error
resp, err := cliente.R().
      SetBody(Article{
        Title: "go-resty",
        Content: "Este es el contenido de mi artículo, ¡oh sí!",
        Author: "Jeevanandam M",
        Tags: []string{"artículo", "ejemplo", "resty"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // O SetError(Error{}).
      Put("https://miaplicacion.com/articulo/1234")

Solicitud PATCH

Puede utilizar varias combinaciones de la llamada del método PATCH tal como se muestra para POST.

// Nota: Este es un ejemplo de uso del método PATCH, para más combinaciones consulte POST

// Crear un cliente Resty
cliente := resty.New()

// Enviar solicitud con tipo de contenido JSON
// Si hay ajustes a nivel de cliente, se puede omitir el token de autenticación, error
resp, err := cliente.R().
      SetBody(Article{
        Tags: []string{"nueva etiqueta 1", "nueva etiqueta 2"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // O SetError(Error{}).
      Patch("https://miaplicacion.com/articulos/1234")

Solicitud DELETE, HEAD, OPTIONS

// Crear un cliente Resty
cliente := resty.New()

//Eliminar un artículo
// Si hay ajustes a nivel de cliente, se puede omitir el token de autenticación, error
resp, err := cliente.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // O SetError(Error{}).
      Delete("https://miaplicacion.com/articulos/1234")

// Eliminar varios artículos con una cadena JSON como carga/contenido
// Si hay ajustes a nivel de cliente, se puede omitir el token de autenticación, error
resp, err := cliente.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // O SetError(Error{}).
      SetHeader("Content-Type", "application/json").
      SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
      Delete("https://miaplicacion.com/articulos")

// Obtener la información del encabezado de un recurso
// Si hay ajustes a nivel de cliente, se puede omitir el token de autenticación
resp, err := cliente.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Head("https://miaplicacion.com/videos/video-alta-resolucion")

// Obtener la información de las opciones de un recurso
// Si hay ajustes a nivel de cliente, se puede omitir el token de autenticación
resp, err := cliente.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Options("https://miaplicacion.com/servidores/nyc-dc-01")

Configuración de Operaciones de Serialización/Deserialización JSON y XML

Los usuarios pueden registrar sus bibliotecas JSON/XML elegidas con resty, o escribir sus propias bibliotecas. Por defecto, resty registra las bibliotecas estándar encoding/json y encoding/xml.

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

json := jsoniter.ConfigCompatibleWithStandardLibrary

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

// De manera similar, los usuarios pueden configurar XML de la siguiente manera
cliente.SetXMLMarshaler(xml.Marshal).
    SetXMLUnmarshaler(xml.Unmarshal)