Go Resty là một thư viện ngôn ngữ Go dùng để xây dựng các client RESTful API. Với Go Resty, các nhà phát triển có thể xây dựng các client RESTful API đáng tin cậy một cách nhanh chóng và hiệu quả hơn. Chương này giới thiệu cách bắt đầu nhanh chóng với Go Resty.

Cài đặt

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

hoặc

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

Ví dụ sử dụng Resty

Các ví dụ sau sẽ giúp bạn sử dụng thư viện resty một cách thoải mái nhất.

// Nhúng resty vào mã của bạn và tham chiếu nó như là `resty`.
import "github.com/go-resty/resty/v2"

Yêu cầu GET đơn giản

// Tạo một client Resty
client := resty.New()

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

// Khám phá đối tượng phản hồi
fmt.Println("Thông tin phản hồi:")
fmt.Println("  Lỗi         :", err)
fmt.Println("  Mã trạng thái:", resp.StatusCode())
fmt.Println("  Trạng thái   :", resp.Status())
fmt.Println("  Giao thức   :", resp.Proto())
fmt.Println("  Thời gian   :", resp.Time())
fmt.Println("  Nhận vào lúc:", resp.ReceivedAt())
fmt.Println("  Nội dung    :\n", resp)
fmt.Println()

// Khám phá thông tin theo dõi
fmt.Println("Thông tin theo dõi yêu cầu:")
ti := resp.Request.TraceInfo()
fmt.Println("  DNS tìm kiếm       :", ti.DNSLookup)
fmt.Println("  Thời gian kết nối :", ti.ConnTime)
fmt.Println("  Thời gian kết nối TCP:", ti.TCPConnTime)
fmt.Println("  Handshake TLS  :", ti.TLSHandshake)
fmt.Println("  Thời gian máy chủ   :", ti.ServerTime)
fmt.Println("  Thời gian phản hồi   :", ti.ResponseTime)
fmt.Println("  Thời gian tổng cộng  :", ti.TotalTime)
fmt.Println("  Đã kết nối lại  :", ti.IsConnReused)
fmt.Println("  Kết nối đã nghỉ  :", ti.IsConnWasIdle)
fmt.Println("  Thời gian nghỉ kết nối  :", ti.ConnIdleTime)
fmt.Println("  Yêu cầu thử lại  :", ti.RequestAttempt)
fmt.Println("  Địa chỉ từ xa  :", ti.RemoteAddr.String())
Kết quả
Thông tin phản hồi:
  Lỗi         : 
  Mã trạng thái: 200
  Trạng thái   : 200 OK
  Giao thức   : HTTP/2.0
  Thời gian   : 457.034718ms
  Nhận vào lúc: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
  Nội dung    :
  {
    "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"
  }

Thông tin theo dõi yêu cầu:
  DNS tìm kiếm       : 4.074657ms
  Thời gian kết nối : 381.709936ms
  Thời gian kết nối TCP: 77.428048ms
  Handshake TLS  : 299.623597ms
  Thời gian máy chủ   : 75.414703ms
  Thời gian phản hồi   : 79.337µs
  Thời gian tổng cộng  : 457.034718ms
  Đã kết nối lại  : false
  Kết nối đã nghỉ  : false
  Thời gian nghỉ kết nối  : 0s
  Yêu cầu thử lại  : 1
  Địa chỉ từ xa  : 3.221.81.55:443

Yêu cầu GET phức tạp

// Tạo một client Resty
client := resty.New()

// Đặt các tham số truy vấn
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")


// Ví dụ sử dụng phương thức Request.SetQueryString
resp, err := client.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")


// Nếu cần, buộc kiểu nội dung phản hồi cụ thể để chỉ dẫn Resty phân tích phản ứng JSON thành cấu trúc của bạn
resp, err := client.R().
      SetResult(result).
      ForceContentType("application/json").
      Get("v2/alpine/manifests/latest")

Các ví dụ yêu cầu POST khác nhau

// Tạo một client Resty
client := resty.New()

// POST chuỗi JSON
// Nếu cài đặt cấp client đã được thiết lập, loại nội dung không cần phải được đặt
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      SetResult(&AuthSuccess{}).    // hoặc SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// POST mảng []byte
// Nếu cài đặt cấp client đã được thiết lập, loại nội dung không cần phải được đặt
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
      SetResult(&AuthSuccess{}).    // hoặc SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// POST struct, mặc định là loại nội dung JSON, không cần phải đặt
resp, err := client.R().
      SetBody(User{Username: "testuser", Password: "testpass"}).
      SetResult(&AuthSuccess{}).    // hoặc SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // hoặc SetError(AuthError{}).
      Post("https://myapp.com/login")

// POST map, mặc định là loại nội dung JSON, không cần phải đặt
resp, err := client.R().
      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
      SetResult(&AuthSuccess{}).    // hoặc SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // hoặc SetError(AuthError{}).
      Post("https://myapp.com/login")

// Tải tệp lên dưới dạng mảng byte không xử lý. Ví dụ: Tải tệp lên Dropbox
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")

// Lưu ý rằng chúng ta không đặt tiêu đề loại nội dung vì go-resty sẽ tự động phát hiện Content-Type
resp, err := client.R().
      SetBody(fileBytes).
      SetContentLength(true).          // Dropbox yêu cầu giá trị này
      SetAuthToken("").
      SetError(&DropboxError{}).       // hoặc SetError(DropboxError{}).
      Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // DropBox cũng hỗ trợ tải lên phương thức PUT

// Lưu ý: Nếu tiêu đề loại nội dung không được đặt, resty sẽ phát hiện ra Loại nội dung của cơ thể yêu cầu
//   * Đối với các cấu trúc và kiểu dữ liệu bản đồ, mặc định là 'application/json'
//   * Sau đó nó là loại nội dung văn bản bình thường

Yêu cầu PUT

Bạn có thể sử dụng các kết hợp khác nhau của cuộc gọi phương thức PUT giống như đã được minh họa cho POST.

// Lưu ý: Đây là một ví dụ về việc sử dụng phương thức PUT, để biết thêm các kết hợp vui lòng tham khảo POST

// Tạo một client Resty
client := resty.New()

// Gửi yêu cầu với kiểu nội dung JSON
// Nếu có cài đặt cấp độ client, mã thông báo xác thực có thể được bỏ qua, lỗi
resp, err := client.R().
      SetBody(Article{
        Title: "go-resty",
        Content: "Đây là nội dung bài viết của tôi, oh yeah!",
        Author: "Jeevanandam M",
        Tags: []string{"bài viết", "ví dụ", "resty"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Hoặc SetError(Error{}).
      Put("https://myapp.com/article/1234")

Yêu cầu PATCH

Bạn có thể sử dụng các kết hợp khác nhau của cuộc gọi phương thức PATCH giống như đã được minh họa cho POST.

// Lưu ý: Đây là một ví dụ về việc sử dụng phương thức PATCH, để biết thêm các kết hợp vui lòng tham khảo POST

// Tạo một client Resty
client := resty.New()

// Gửi yêu cầu với kiểu nội dung JSON
// Nếu có cài đặt cấp độ client, mã thông báo xác thực có thể được bỏ qua, lỗi
resp, err := client.R().
      SetBody(Article{
        Tags: []string{"thẻ mới 1", "thẻ mới 2"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Hoặc SetError(Error{}).
      Patch("https://myapp.com/articles/1234")

DELETE, HEAD, OPTIONS Yêu cầu

// Tạo một client Resty
client := resty.New()

// Xóa một bài viết
// Nếu có cài đặt cấp độ client, mã thông báo xác thực có thể được bỏ qua, lỗi
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Hoặc SetError(Error{}).
      Delete("https://myapp.com/articles/1234")

// Xóa nhiều bài viết với chuỗi JSON là nội dung
// Nếu có cài đặt cấp độ client, mã thông báo xác thực có thể được bỏ qua, lỗi
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // Hoặc SetError(Error{}).
      SetHeader("Content-Type", "application/json").
      SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
      Delete("https://myapp.com/articles")

// Lấy thông tin tiêu đề của một tài nguyên
// Nếu có cài đặt cấp độ client, mã thông báo xác thực có thể được bỏ qua
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Head("https://myapp.com/videos/hi-res-video")

// Lấy thông tin tùy chọn của một tài nguyên
// Nếu có cài đặt cấp độ client, mã thông báo xác thực có thể được bỏ qua
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Options("https://myapp.com/servers/nyc-dc-01")

Thiết lập hoạt động Serialization/Deserialization JSON và XML

Người dùng có thể đăng ký thư viện JSON/XML mà họ chọn với resty, hoặc viết thư viện của riêng họ. Theo mặc định, resty đăng ký các thư viện chuẩn encoding/jsonencoding/xml.

// Ví dụ về việc đăng ký json-iterator
import jsoniter "github.com/json-iterator/go"

json := jsoniter.ConfigCompatibleWithStandardLibrary

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

// Tương tự, người dùng có thể thiết lập XML như sau -
client.SetXMLMarshaler(xml.Marshal).
    SetXMLUnmarshaler(xml.Unmarshal)