Interceptor — その概要、OkHttpとAlamofireのインターセプターの種類

著者: IT Sectr 公開日: 2026-03-08 読了時間: 8 分

InterceptorはOkHttpとAlamofireのコンポーネントで、ロギング、認証、キャッシング、再試行のためにHTTPリクエストとレスポンスをインターセプトします。Square (2026)によると、適切に設定されたインターセプターはネットワークデバッグ時間を40%削減し、エラーハンドリングを標準化します。Application Interceptorはリクエストごとに1回実行され、Network Interceptorはリダイレクトごとに実行されます。

主要ポイント

  • Interceptor — 横断的関心事のためにOkHttpとAlamofireでHTTPリクエストとレスポンスをインターセプトするコンポーネント。
  • Application InterceptorはアプリケーションとOkHttpの間でリクエストの前後に1回実行されます。
  • Network InterceptorはOkHttp内の各リダイレクトと再試行で実行されます。
  • RequestInterceptorはAlamofireでリクエスト適応と再試行を組み合わせます。
  • Chain.proceed() — リクエストをインターセプターチェーンに沿って渡すOkHttpの主要メソッド。

Interceptorとは?

Interceptorは、HTTPクライアントに注入されるソフトウェアコンポーネントで、サーバーに送信される前のリクエストとアプリケーションに到達する前のレスポンスをインターセプトして変更します。モバイル開発では、インターセプターは横断的関心事を処理します:自動認証トークン注入、時間測定付きトラフィックロギング、一時的なネットワークエラー時の再試行、その場でのデータ圧縮と復号化。InterceptorアーキテクチャはChain of Responsibilityパターンに基づいています — 各インターセプターはリクエストを変更、実行、またはカスタムレスポンスを返してチェーンを中断できます。

インターセプターチェーンの仕組み

OkHttpでは、インターセプターがチェーンを形成します。各Interceptorは元のリクエストを持つChainオブジェクトを受け取り、chain.proceed(request)を呼び出して次のインターセプターに制御を渡します。レスポンスを受け取った後、インターセプターはResponseを分析、変更、エラー時にリクエストを再試行、またはキャッシング用のカスタムレスポンスを返すことができます。OkHttpClient.Builderへのインターセプターの追加順序が実行順序を決定します:最初に追加されたものが送信時に最初に、受信時に最後に実行されます。

OkHttpのInterceptor: ApplicationとNetwork

OkHttpはインターセプターを2つのタイプに分類します。Application Interceptor (addInterceptor)はアプリケーションコードとOkHttpの間で実行されます:1回のchain.proceed()呼び出し — リダイレクトに関係なくサーバーへの1リクエスト。Network Interceptor (addNetworkInterceptor)はヘッダー形成と接続後にOkHttp内部で実行され、各リダイレクト、再試行、認証試行で発動します。この区別は特定のタスクに適したインターセプタータイプを選択するために重要です。

kotlin
class LoggingInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        Log.d("HTTP", "${request.method} ${request.url}")

        val startTime = System.currentTimeMillis()
        val response = chain.proceed(request)
        val duration = System.currentTimeMillis() - startTime

        Log.d("HTTP", "${response.code} in ${duration}ms")
        return response
    }
}

val client = OkHttpClient.Builder()
    .addInterceptor(LoggingInterceptor())
    .addNetworkInterceptor(CacheInterceptor())
    .build()

LoggingInterceptor — メソッド、URL、レスポンスコード、実行時間をログ記録するApplication Interceptor。addInterceptor()で追加すると、リダイレクトでの重複なしにユーザーリクエストごとに1つのログが保証されます。CacheInterceptorは、HTTPリクエスト形成後にOkHttp内部でのみ表示されるサーバーのCache-Controlヘッダーを考慮するためにNetwork Interceptorとして追加されます。

実際のタイプ間の違い

アプリケーションがリクエストを行うと、サーバーは302または301リダイレクトで応答する場合があります。Application Interceptorはすべてのリダイレクト後の最終レスポンスのみを表示します — 中間リクエストがいくつ行われたかはわかりません。Network Interceptorは中間を含むすべてのリクエストとレスポンスを表示します。Square (2026)によると、Network Interceptorは接続レベルで圧縮されたデータ(gzip)も表示しますが、Application Interceptorは既に解凍されたレスポンスを受け取ります。実際のネットワーク呼び出し数をカウントするにはNetwork Interceptorを使用してください。

Alamofire RequestInterceptor

AlamofireRequestInterceptorプロトコルを提供し、これは2つのプロトコルを組み合わせます:送信前にリクエストを変更するRequestAdapterと、エラー時に再試行するRequestRetrierです。この分離により、適応(ヘッダー、トークンの追加)と再試行ポリシー(指数バックオフ、試行制限、エラータイプチェック)を柔軟に組み合わせることができます。RequestInterceptorは両方のプロトコルに準拠する単一の構造体またはクラスで実装されます。

swift
struct AuthInterceptor: RequestInterceptor {
    private let tokenProvider: TokenProvider

    func adapt(_ urlRequest: URLRequest,
                using state: Session.RequestAdapterState,
                completion: @escaping (Result<URLRequest, Error>) -> Void) {
        var request = urlRequest
        request.setValue("Bearer \(tokenProvider.token)",
                        forHTTPHeaderField: "Authorization")
        completion(.success(request))
    }

    func retry(_ request: Request,
               for session: Session,
               dueTo error: Error,
               completion: @escaping (RetryResult) -> Void) {
        if error is URLError {
            completion(.retryWithDelay(1))
        } else {
            completion(.doNotRetry)
        }
    }
}

AuthInterceptorはSwiftでadaptを介してBearerトークンを追加し、1秒の遅延でretryを介してURLError(ネットワーク喪失、タイムアウト)時に自動的にリクエストを再試行します。適応と再試行を分離することで独立してテストできます — 再試行ロジックに影響を与えずに適応の単体テストを記述できます。Alamofire (2026)によると、RequestInterceptorはiOSプロジェクトで認証管理を集中化する標準的な方法です。

インターセプターのユースケース

ロギング — 最も一般的なユースケース。InterceptorはURL、メソッド、ヘッダー、リクエストとレスポンスの本文、実行時間を記録します。デバッグビルドではCharles ProxyやWiresharkの代わりとなり、リリースビルドではリクエストコンテキストを含むクラッシュレポートに役立ちます。OkHttpはlogging-interceptorライブラリのHttpLoggingInterceptorをNONE、BASIC、HEADERS、BODYのレベルで使用します。BODYレベルは完全なリクエストとレスポンス本文をログ記録します — デバッグのみで使用してください。

認証とトークンリフレッシュ

アクセストークンの有効期限が切れると、Interceptorは401レスポンスをインターセプトし、リフレッシュトークンAPIを呼び出し、新しいトークンで元のリクエストを再試行します。OkHttpでは、Authenticatorまたはresponse.codeチェック付きのカスタムInterceptorを介して実装されます。Authenticatorはレスポンスヘッダーにのみアクセスでき、Interceptorは完全な本文にアクセスできます。AlamofireではRequestRetrierを介して、トークンリフレッシュ後に.retryを返します。OWASP (2026)によると、Interceptorによる自動トークンリフレッシュは認証情報漏洩のリスクを低減します。

共通ヘッダーの追加

Content-Type、Accept-Language、User-Agent、Device-ID — すべてのリクエストで必要なヘッダー。Interceptorは各APIメソッドでの重複なしにこれらを中央で追加します。User-Agentはアプリ起動時に1回形成されます:「AppName/1.0 (Android 14; Pixel 8)」。Accept-Languageはデバイスのシステム言語から取得されます。Alamofire (2026)によると、Interceptorによる集中ヘッダー管理は誤ったヘッダーエラーを30%削減します。

シナリオOkHttpAlamofire
ロギングHttpLoggingInterceptorEventMonitor
認証トークンAuthenticator + InterceptorRequestInterceptor
ヘッダーaddInterceptorRequestAdapter
再試行再試行付きInterceptorRequestRetrier
キャッシングCacheInterceptorCachedResponseHandler

ベストプラクティスとチェーン順序

OkHttpでのInterceptor追加順序はチェーン全体の動作を決定します。最初に追加されたインターセプターはリクエスト送信時に最初に、レスポンス受信時に最後に実行されます。ロギングの場合はInterceptorを最初に追加します — 他のインターセプターからのすべての変更を含む最終リクエストを確認できます。圧縮の場合は最後に追加して、圧縮が最終データに適用されるようにします。認証の場合は再試行前に追加して、次の試行前にトークンがリフレッシュされるようにします。

プロダクションビルドの推奨事項

リリースビルドでは、BuildConfig.DEBUGまたは依存性注入を介してロギングを無効にします。キャッシングにはaddNetworkInterceptorを使用します — Network InterceptorはサーバーのCache-Controlヘッダーを確認し、キャッシングポリシーを正しく解釈します。認証にはaddInterceptor(Application)を使用します — これにより、認証ヘッダーを送信すべきでないサードパーティドメインへのリダイレクトでの再インターセプトを防ぎます。okhttp-testing-supportのMockWebServerを使用して各Interceptorを個別にテストします — リクエストをインターセプトし、事前準備されたレスポンスを返すため、実際のサーバーなしでインターセプターロジックを検証できます。

Interceptorのパフォーマンス

各Interceptorはリクエスト時間にわずかな遅延を追加します。3〜4つのインターセプター(ロギング、認証、圧縮、キャッシング)の典型的なチェーンでは、オーバーヘッドはリクエストあたり5ミリ秒未満です。Interceptorがブロッキング操作を実行すると問題が発生します:同期リフレッシュトークンAPI呼び出し、大きなログのファイルへの書き込み、リクエスト本文の暗号化など。これらの操作はすべて非同期であるか、バックグラウンドスレッドで実行される必要があります。Square (2026)によると、OkHttpはDispatcherスレッドプールでInterceptorを実行します — 1つのインターセプターをブロックするとチェーン全体が遅延します。

  • 順序が重要 — ロギング最初、再試行前に認証、圧縮最後
  • デバッグとリリース — HttpLoggingInterceptorはデバッグビルドのみ
  • 分離 — 各Interceptorは1つのタスクを処理(単一責任)
  • 非同期性 — InterceptorはOkHttpのバックグラウンドスレッドで実行され、UIをブロックしない

よくある質問

OkHttpのaddInterceptorとaddNetworkInterceptorの違いは?

addInterceptor(Application)はアプリケーションとOkHttpの間で1回実行され、リダイレクトや接続圧縮を認識しません。addNetworkInterceptor(Network)は各ネットワーク呼び出しでOkHttp内部で実行され、リダイレクト、再試行、圧縮後のデータを認識します。ロギングと認証にはApplication、キャッシングにはNetworkを選択してください。

Interceptorはどのように自動的にトークンをリフレッシュしますか?

インターセプターはresponse.code == 401をチェックし、RetrofitまたはURLSessionを介して非同期リフレッシュトークンAPIを呼び出し、新しいトークンを保存して元のリクエストを再試行します。OkHttpではBasic AuthにAuthenticator、リフレッシュ付きBearerにInterceptorを使用します。Alamofireではエラータイプチェック付きのretryを使用します。

Interceptorはアプリケーションを遅くする可能性がありますか?

はい — Interceptorでの重い操作(大きな本文のロギング、暗号化、同期API呼び出し)は応答時間を増加させます。非同期コールバックを使用し、BuildConfig.DEBUGを介してデバッグビルドのみにロギングを制限し、interceptメソッドでブロッキング操作を実行しないでください。

OkHttpのAuthenticatorとは何ですか?Interceptorとどう違いますか?

Authenticatorは401レスポンス用の特殊なインターセプターで、Basic AuthまたはBearerトークンを実装します。Authenticatorはリクエスト本文にアクセスできず、送信前にヘッダーを変更できません — 認証エラーレスポンスのみを処理します。一方、Interceptorは実行のどの段階でもリクエストを変更できます。

同じInterceptorをすべてのリクエストに追加するには?

OkHttpでは、InterceptorをOkHttpClient.Builderに渡します — このクライアントからのすべてのリクエストがそれを通過します。Alamofireでは、Session設定にRequestInterceptorを追加します。複数のクライアントを使用する場合(例:異なるAPI用)、Builderパターンを使用して共通のインターセプターを持つベースBuilderを作成します。

まとめ

  • Interceptor — Chain of Responsibilityパターンに基づくHTTPリクエストとレスポンスのインターセプト機構。
  • OkHttpは2つのタイプを提供:Application(リクエストごとに1回の呼び出し)とNetwork(各リダイレクトと再試行時)。
  • Alamofireは単一のRequestInterceptorで適応(RequestAdapter)と再試行(RequestRetrier)を分離。
  • 主なユースケース — ロギング、認証、ヘッダー、再試行、HTTPレスポンスのキャッシング。
  • BuilderへのInterceptor追加順序が実行順序を決定:ロギング最初、圧縮最後。
  • プロダクションビルドではBuildConfigフラグとDI注入を介してデバッグロギングを無効にする必要があります。
  • 適切に設定されたインターセプターチェーンはネットワークデバッグ時間を40%削減し、エラーハンドリングを標準化します。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください