今関わっているプロジェクトではOpenAPIを利用して、APIのスキーマを定義しています。OpenAPIではスキーマ定義からクライアントコードを生成できます。デフォルトのコード生成はスキーマ定義とネットワーク通信のコードが強く結びついており、使いにくい場面があると感じていました。認証等がなく、単純なGETだけのエンドポイントを相手にしている場合はそうなっているのは便利だと思いますが、今のプロジェクトではリクエストヘッダに認証トークンおよびアプリの情報を示す情報を追加する(デバッグビルドでは)リクエスト前と後にログ出力をするアクセストークンの期限が切れた場合は自動的にアクセストークンをリフレッシュし、シームレスにリトライするすべてのエンドポイントで発生しうるエラー(サーバーエラーの5xxや、クライアントエラーの4xx、強制アップデートや緊急メンテナンスなど)と、個々のエンドポイントでのみ起こるエラー、認証のエンドポイントでのみ起こるエラーを適切にハンドリングするというそこそこ複雑な処理をする必要があります。問題OpenAPIのコード生成はデフォルトではAlamofireに依存していて、通信処理の大部分はAlamofireが担当しますが、OAuth2のサポートはデフォルトでは無いので認証は別のOAuth2ライブラリと組み合わせることで実現していました。問題に感じていたことは主にAPIの追加・更新時に挙動がおかしい場合の調査・デバッグです。前述のようにAPIの通信に関係する処理は、OpenAPIの自動生成コード(スキーマの定義とパラメータの加工とエンコード、レスポンスのデコードなどが含まれる)、Alamofireのコード、OAuth2ライブラリのコード、アプリケーションコード、の4つにまたがり、そのうちの3つは第三者が書いたライブラリのコードです。複数のライブラリのコードをスイッチして調査することは問題の調査をかなりややこしくしていました。問題の解決その問題を解決するために、OpenAPIによるコード生成はAPIのスキーマ定義だけのシンプルなもの(自動生成コードをデバッグするのはつらい)にし、通信処理もシンプルなクライアントを自分で書くことにしました。してできあがったのがこちらのライブラリです。github.comもともとのOpenAPIが生成する通信のコードは、非常に汎用的になっているため、現在のプロジェクトには関係のないコードが数多く存在しました。このAPIClientでは、一般的なAPIクライアントでは実装すべき処理も、プロジェクトで使用してないものは対応しないことでシンプルに誰でも読めるように書かれています。OpenAPIのスキーマ定義から生成したコードを利用することが前提であることも、シンプルさに役立っています。OpenAPIのコード生成は次のように変更しました。通信処理に必要なヘルパークラスはすべて無くして、パラメータとレスポンスに使用されるモデル(変更なし)とエンドポイントの定義のみを生成するようにしました。エンドポイントのコードは下記のようになります。RequestProvider.Parameters(parameters))}...APIリクエストに必要なエンドポイントの定義は、URL、HTTPメソッドの種類、パラメータの型およびエンコーディング、レスポンスの型、が必要です。作り直したコード生成のテンプレートは上記の情報をRequestProviderという型にエンコードして表現します。RequestProvider<Response>にはAPIリクエストに必要な情報がすべて含まれていますので、これだけ受け取ればAPIリクエストを実行できます。APIクライアントの通信処理はほぼすべてClient.swiftに書かれています。他のファイルはほぼデータ構造やプロトコルを定義しているだけのファイルなので、処理は記述されていないので見る必要がありません。Client.swiftはURLSessionを使った典型的な通信処理が書かれていて、非同期のコールバックによるネストと、シームレスなリトライ処理のためループする構造になっているところがやや複雑に見えますが、基本的に上から下に読んでいけばわかるように単純に記述されています。APIClientとOpenAPIのスキーマ定義を個別にビルド可能にしたかったので、RequestBuilder<Response>からAPIClientが使うRequest<Response>に型を変換するコードをアプリケーション側に書きます。}}ログ出力やエラーハンドリング、トークンリフレッシュを伴う自動リトライなどはOkHttpを参考にしてInterceptorという仕組みでリクエストの前後の処理をフックできるようにしました。iOSのスタイルに沿うように、単なる複数登録できるDelegateにしました。ここまでで、OpenAPIのコード生成から通信処理をなくすOpenAPIのコード生成をシンプルに通信処理の簡略化リトライやエラーハンドリングの仕組みを統一によって、従来のデバッグが困難という問題を解決できました。おわりにここで示したコードとライブラリは、現在のプロジェクトに最適化しているため、他のプロジェクトでそのまま使用することには不向きです。Requestも受け付ける予定はありません。考え方や実装方法は参考にはなると考え、公開しています。同様のアプローチで問題を解決しようとするなら、フォークするか、コードをコピーして使用することをおすすめします。下記は認証のリトライと、ログ出力のInterceptorの実装例です。月別アーカイブはてなブログをはじめよう!KishikawaKatsumiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。