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

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

Df3136f800e7ed9931ed5f9f1afad935?s=47 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) 記事もおすすめです。

Df3136f800e7ed9931ed5f9f1afad935?s=128

mtskhs

October 28, 2019
Tweet

Transcript

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

  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
  3. SpoLive 3

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

  5. Bad Example of API Client • `net/http` を使えば簡単?! 5 Sample

    API from https://noopschallenge.com
  6. Bad Example of API Client 考えるべきこと 6 • エラーコード(200 OK以外)が返

    却されたら? • ネットワークが一時的に切断され たら? • 利用するAPIが複雑化(認証が追 加される・リクエストの種類増える 等)したら? • `net/http` を使えば簡単?!
  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
  8. Error handling • HTTP Status・レスポンスの内容 等に応じて、エラーをどう扱うべき か定義しておく • リトライできるか・何も処理しない か

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

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

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

  12. Idempotency - 冪等性の担保 よくある事例 • 100件のPOST通信のうち90件は成功・10件失敗した場合、 すでに処理済みのものを再度POSTしたら、処理済エラーが返却され てバッチがコケる • サービスAへの処理は成功したが、サービスBへの処理は失敗した

    (RDBでいうトランザクション) 解決策 • 手元で、処理IDと処理ステータスをもたせる ◦ 成功した90件: 処理済 / 失敗の10件: 未処理のまま ◦ サービスAは成功 / Bは未処理 (リトライ or Aの取り消し) 12
  13. Highly scalable design - 汎用的な実装 • request生成時に考えること ◦ ドメインは初期設定 +

    リクエスト毎にURL Path設定 ◦ 各リクエストに、共通のHeader追加 ◦ リクエストごとに、固有のHeader追加 13
  14. Highly scalable design - 汎用的な実装 Clientの実装 • ドメイン設定 • 共通Header

    14
  15. Highly scalable design - 汎用的な実装 Request生成 • Method • URL

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

    • URL Path • 個別Header 16
  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
  18. https://mholt.github.io/json-to-go/ 18 JSON decode pattern - Go Struct sampleデータから、GoのStructを生成する

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

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

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

  22. Testing strategy 課題:APIリクエストができる環境には制限がある API Clientに関するTest技法 • interfaceとして切り出す(client全体をmock) • httptest を用いたE2Eテスト

    • Symmetric API Testingの概念 (レスポンスを保存しておく) 22
  23. Testing strategy clientをinterfaceとして切り出しておくと、利用側のテストが容易に 23 usecase/main.go usecase/main_test.go

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

  25. Testing strategy “Symmetric API Testing” • レスポンス結果をローカルディスクに保存 • テストに上記ファイルを利用して試験(httptestレスポンスとして設定する等) 25

    refer from: https://deeeet.com/writing/2016/10/25/go-interface-testing/
  26. Testing strategy 26 refer from: https://deeeet.com/writing/2016/10/25/go-interface-testing/ “Symmetric API Testing” •

    レスポンス結果をローカルディスクに保存 • テストに上記ファイルを利用して試験(httptestレスポンスとして設定する等)
  27. Summary API Clientの実装パターンを、サンプルコードと共に体系的に紹介 1. 重要な概念とGoにおける実装 • エラー時のリトライ処理、冪等性の担保、 汎用的な設計 2. よくある実装パターン

    • JSON decode pattern、認証、test技法 27 Sample Code : https://github.com/matsu0228/apiClientExample-GoConference2019Autumn
  28. SpoLive - https://spo.live/ ラグビー国際試合に対応しました! 28