Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Goにおける API Client実装パターン / API Client implementation pattern in Go

mtskhs
October 28, 2019

Goにおける API Client実装パターン / API Client implementation pattern in Go

Go Conference 2019 Autumn における登壇資料(Level:Beginner)です。

- マイクロサービスアーキテクチャによる開発が普及してきている現在、REST APIにおけるHTTPリクエスト処理が求められる場面は多い。その際、APIリクエストに関する重要な概念を理解し、Clientとして適切に実装することが求められる。

- 本発表では、マイクロサービス間のデータ連携システムを開発・運用した経験を持つ発表者が、HTTPリクエスト処理に関する「重要な概念とGoにおける実装パターン」や「よくある実装パターン」について述べる。

- サンプルコード:https://github.com/matsu0228/apiClientExample-GoConference2019Autumn
- Goにおけるテストについては、 [AgileTestingDays2018に参加して、Goにおけるテストノウハウを整理した](https://qiita.com/matsu0228/items/c9f69b036f0ab47b617e) 記事もおすすめです。

mtskhs

October 28, 2019
Tweet

More Decks by mtskhs

Other Decks in Technology

Transcript

  1. GoにおけるAPI Client
    実装パターン
    Hisayuki Matsuki (@mtskhs)
    Go Conference 2019 Autumn

    View Slide

  2. About me
    松木久幸 @mtskhs
    Backend Engineer
    Gopher Dojo 1期生
    2
    Service
    ● EC @ NTT Resonant
    ● スポーツAI解説アプリ(SpoLive)
    @ NTT Communications
    Interest
    ● Agile (シリコンバレーで3ヶ月働いて
    体感した自律型組織のススメ)
    https://speakerdeck.com/matsu0228/organizationtheory-of-engineering
    ● Agile Testing Days 2018 レポート
    https://speakerdeck.com/matsu0228/report-of-agiletestingdays2018

    View Slide

  3. SpoLive
    3

    View Slide

  4. API Client
    マイクロサービスアーキテクチャによる開発が普及している現在、REST API
    におけるHTTPリクエスト処理が求められる場面は多い
    4
    https://microservices.io/

    View Slide

  5. Bad Example of API Client
    ● `net/http` を使えば簡単?!
    5
    Sample API from https://noopschallenge.com

    View Slide

  6. Bad Example of API Client
    考えるべきこと
    6
    ● エラーコード(200 OK以外)が返
    却されたら?
    ● ネットワークが一時的に切断され
    たら?
    ● 利用するAPIが複雑化(認証が追
    加される・リクエストの種類増える
    等)したら?
    ● `net/http` を使えば簡単?!

    View Slide

  7. Contents
    1. 重要な概念とGoにおける実装
    1.1. エラー時のリトライ処理
    1.2. 冪等性の担保
    1.3. RequestOptionsを用いた汎用的な設計
    2. よくある実装パターン
    2.1. JSON decode pattern
    2.2. 認証
    2.3. Test設計
    7
    Sample Code :
    https://github.com/matsu0228/apiClientExample-GoConference2019Autumn

    View Slide

  8. Error handling
    ● HTTP Status・レスポンスの内容
    等に応じて、エラーをどう扱うべき
    か定義しておく
    ● リトライできるか・何も処理しない
    か etc
    8

    View Slide

  9. “Exponential Backoff
    エクスポネンシャルバックオフは、再試行間の待機時間を累進
    的に長くして、連続的なエラー応答を受信するという考えに基づ
    いています。最大遅延間隔で最大回数の再試行を実行する必
    要があります。再試行の最大遅延間隔と最大回数は必ずしも固
    定値ではなく、実行する操作や局所的な要因 (ネットワークのレ
    イテンシーなど) に基づいて設定する必要があります。
    9
    Retrying
    https://docs.aws.amazon.com/ja_jp/general/latest/gr/api-retries.html

    View Slide

  10. Retrying
    Exponential Backoff の考えに基づきリトライする効用
    ● APIサーバー側からみて、Client数が増えたときにも捌ける
    Request数を最大化できる
    10
    https://aws.amazon.com/jp/blogs/architecture/exponential-backoff-and-jitter/

    View Slide

  11. Retrying
    Exponential Backoff
    によるリトライの
    ライブラリ例:
    github.com/cenkalti/bac
    koff
    11

    View Slide

  12. Idempotency - 冪等性の担保
    よくある事例
    ● 100件のPOST通信のうち90件は成功・10件失敗した場合、
    すでに処理済みのものを再度POSTしたら、処理済エラーが返却され
    てバッチがコケる
    ● サービスAへの処理は成功したが、サービスBへの処理は失敗した
    (RDBでいうトランザクション)
    解決策
    ● 手元で、処理IDと処理ステータスをもたせる
    ○ 成功した90件: 処理済 / 失敗の10件: 未処理のまま
    ○ サービスAは成功 / Bは未処理 (リトライ or Aの取り消し)
    12

    View Slide

  13. Highly scalable design - 汎用的な実装
    ● request生成時に考えること
    ○ ドメインは初期設定
    + リクエスト毎にURL Path設定
    ○ 各リクエストに、共通のHeader追加
    ○ リクエストごとに、固有のHeader追加
    13

    View Slide

  14. Highly scalable design - 汎用的な実装
    Clientの実装
    ● ドメイン設定
    ● 共通Header
    14

    View Slide

  15. Highly scalable design - 汎用的な実装
    Request生成
    ● Method
    ● URL Path
    ● 個別Header
    15

    View Slide

  16. Highly scalable design - 汎用的な実装
    各Requestでは差
    分だけ設定すれ
    ばよい
    ● Method
    ● URL Path
    ● 個別Header
    16

    View Slide

  17. Contents
    1. 重要な概念とGoにおける実装
    1.1. エラー時のリトライ処理
    1.2. 冪等性の担保
    1.3. RequestOptionsを用いた汎用的な設計
    2. よくある実装パターン
    2.1. JSON decode pattern
    2.2. 認証
    2.3. Test設計
    17
    Sample Code :
    https://github.com/matsu0228/apiClientExample-GoConference2019Autumn

    View Slide

  18. https://mholt.github.io/json-to-go/
    18
    JSON decode pattern - Go Struct
    sampleデータから、GoのStructを生成する

    View Slide

  19. 19
    JSON decode pattern - Decode
    よくある実装パターン:
    response.Bodyから構造体を生成する関数を用意 testableな実装を心がける。

    View Slide

  20. 20
    JSON decode pattern - Delay parsing
    JSONがステータスに応じて構造が変化する場合、
    “json.RawMessage” を利用し遅延評価する
    https://godoc.org/encoding/json#RawMessage

    View Slide

  21. Authorization
    APIの要件にあった認証ヘッダの設定
    e.g. アカウント毎に発行されたキーの
    base64エンコードしたものをヘッダに付与してアクセス。発行
    キー”aabbcc:ddeecc”なら”Authorization: Basic YWFiYmNjOmRkZWVjYw==”
    21

    View Slide

  22. Testing strategy
    課題:APIリクエストができる環境には制限がある
    API Clientに関するTest技法
    ● interfaceとして切り出す(client全体をmock)
    ● httptest を用いたE2Eテスト
    ● Symmetric API Testingの概念 (レスポンスを保存しておく)
    22

    View Slide

  23. Testing strategy
    clientをinterfaceとして切り出しておくと、利用側のテストが容易に
    23
    usecase/main.go usecase/main_test.go

    View Slide

  24. Testing strategy
    net/http/httptest を利用しlocalhost
    にAPIServerを立ち上げることによる
    E2Eテスト
    24

    View Slide

  25. Testing strategy
    “Symmetric API Testing”
    ● レスポンス結果をローカルディスクに保存
    ● テストに上記ファイルを利用して試験(httptestレスポンスとして設定する等)
    25
    refer from: https://deeeet.com/writing/2016/10/25/go-interface-testing/

    View Slide

  26. Testing strategy
    26
    refer from: https://deeeet.com/writing/2016/10/25/go-interface-testing/
    “Symmetric API Testing”
    ● レスポンス結果をローカルディスクに保存
    ● テストに上記ファイルを利用して試験(httptestレスポンスとして設定する等)

    View Slide

  27. Summary
    API Clientの実装パターンを、サンプルコードと共に体系的に紹介
    1. 重要な概念とGoにおける実装
    ● エラー時のリトライ処理、冪等性の担保、
    汎用的な設計
    2. よくある実装パターン
    ● JSON decode pattern、認証、test技法
    27
    Sample Code :
    https://github.com/matsu0228/apiClientExample-GoConference2019Autumn

    View Slide

  28. SpoLive - https://spo.live/
    ラグビー国際試合に対応しました!
    28

    View Slide