Go Restyは、RESTful APIクライアントを構築するためのGo言語ライブラリです。Go Restyを使用すると、開発者はより迅速かつ効率的に信頼性のあるRESTful APIクライアントを構築することができます。この章では、Go Restyを素早く始める方法について紹介します。

Installation

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

または

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

Resty Example

以下の例は、Restyライブラリをできるだけ快適に使用するためのものです。

// コードにrestyをインポートし、「resty」として参照します。
import "github.com/go-resty/resty/v2"

Simple GET Request

// Restyクライアントを作成します
client := resty.New()

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

// レスポンスオブジェクトを調査する
fmt.Println("Response Info:")
fmt.Println("  Error      :", err)
fmt.Println("  Status code:", resp.StatusCode())
fmt.Println("  Status     :", resp.Status())
fmt.Println("  Protocol   :", resp.Proto())
fmt.Println("  Time       :", resp.Time())
fmt.Println("  Received at:", resp.ReceivedAt())
fmt.Println("  Body       :\n", resp)
fmt.Println()

// トラッキング情報を調査する
fmt.Println("Request trace info:")
ti := resp.Request.TraceInfo()
fmt.Println("  DNS lookup      :", ti.DNSLookup)
fmt.Println("  Connect time    :", ti.ConnTime)
fmt.Println("  TCP connect time:", ti.TCPConnTime)
fmt.Println("  TLS handshake   :", ti.TLSHandshake)
fmt.Println("  Server time     :", ti.ServerTime)
fmt.Println("  Response time   :", ti.ResponseTime)
fmt.Println("  Total time      :", ti.TotalTime)
fmt.Println("  Is conn reused  :", ti.IsConnReused)
fmt.Println("  Conn was idle   :", ti.IsConnWasIdle)
fmt.Println("  Conn idle time  :", ti.ConnIdleTime)
fmt.Println("  Request attempt :", ti.RequestAttempt)
fmt.Println("  Remote address  :", ti.RemoteAddr.String())
出力
Response Info:
  Error      : 
  Status code: 200
  Status     : 200 OK
  Protocol   : HTTP/2.0
  Time       : 457.034718ms
  Received at: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
  Body       :
  {
    "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"
  }

Request trace info:
  DNS lookup      : 4.074657ms
  Connect time    : 381.709936ms
  TCP connect time: 77.428048ms
  TLS handshake   : 299.623597ms
  Server time     : 75.414703ms
  Response time   : 79.337µs
  Total time      : 457.034718ms
  Is conn reused  : false
  Conn was idle   : false
  Conn idle time  : 0s
  Request attempt : 1
  Remote address  : 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=buy a lot more").
      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文字列をPOSTする
// クライアントレベルの設定がされている場合、コンテンツタイプを設定する必要はありません
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      SetResult(&AuthSuccess{}).    // またはSetResult(AuthSuccess{})
      Post("https://myapp.com/login")

// []byte配列をPOSTする
// クライアントレベルの設定がされている場合、コンテンツタイプを設定する必要はありません
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody([]byte(`{"username":"testuser", "password":"testpass"`)).
      SetResult(&AuthSuccess{}).    // またはSetResult(AuthSuccess{})
      Post("https://myapp.com/login")

// 構造体をPOSTする(デフォルトはJSONコンテンツタイプであり、設定する必要はありません)
resp, err := client.R().
      SetBody(User{Username: "testuser", Password: "testpass"}).
      SetResult(&AuthSuccess{}).    // またはSetResult(AuthSuccess{})
      SetError(&AuthError{}).       // またはSetError(AuthError{})
      Post("https://myapp.com/login")

// マップをPOSTする(デフォルトは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を検出します
//   * 構造体やマップの場合、デフォルトは 'application/json'
//   * それ以外の場合は通常のテキストコンテンツタイプになります

PUTリクエスト

POSTの場合と同様に、PUTメソッドを使用したさまざまな組み合わせを示したように、PUTメソッドを使用することができます。

// 注意: これはPUTメソッドを使用した例です。他の組み合わせについてはPOSTを参照してください。

// Restyクライアントの作成
client := resty.New()

// JSONコンテンツタイプでリクエストを送信
// クライアントレベルの設定がある場合、認証トークンは省略できます。エラーが発生した場合は
resp, err := client.R().
      SetBody(Article{
        Title: "go-resty",
        Content: "This is my article content, oh yeah!",
        Author: "Jeevanandam M",
        Tags: []string{"article", "example", "resty"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&Error{}).       // またはSetError(Error{}).
      Put("https://myapp.com/article/1234")

PATCHリクエスト

POSTの場合と同様に、PATCHメソッドを使用したさまざまな組み合わせを示したように、PATCHメソッドを使用することができます。

// 注意: これはPATCHメソッドを使用した例です。他の組み合わせについてはPOSTを参照してください。

// Restyクライアントの作成
client := resty.New()

// JSONコンテンツタイプでリクエストを送信
// クライアントレベルの設定がある場合、認証トークンは省略できます。エラーが発生した場合は
resp, err := client.R().
      SetBody(Article{
        Tags: []string{"new tag 1", "new tag 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)