LoginSignup
1
0

More than 1 year has passed since last update.

[Android]OkHttpのタグ機能を活用する

Posted at

OkHttp では Request オブジェクトを作成するときに「タグ」を設定することができます。

このタグについて実用例と共に紹介したいと思います。

また、タグは Retrofit でも設定することができるので、この部分についても紹介します。

タグを使った認証情報の設定

例えば何らかの Web API で、認証が必要なものとそうでないものがあったとします。

認証情報はヘッダで指定する場合、OkHttp でリクエストするなら以下のように記述できます。

val request = Request.Builder()
    .url("...")
    .addHeader("Authorization", "...") // 認証情報を設定.
    .build()

val response = okHttpClient.newCall(request).execute()

このように認証情報が必要なリクエストに対して都度設定しても問題ないですが、タグと Interceptor を組み合わせることによって、認証情報のヘッダの設定を一括で処理させることも可能です。

まずは Request オブジェクトを生成するときに、このリクエストでは「認証情報を設定する必要がある」というタグを設定します。

// タグオブジェクト.
// このタグが設定されているリクエストには、Authorization ヘッダが必要。
object RequireAuthorizationTag

val request = Request.Builder()
    .url("xxx")
    .tag(RequireAuthorizationTag::class.java, RequireAuthorizationTag) // タグを設定する.
    .build()

val response = okHttpClient.newCall(request).execute()

そして Interceptor を継承した AddAuthorizationHeaderInterceptor を作成し、ここでタグが設定されているリクエストに対して Authorization ヘッダを指定します。

class AddAuthorizationHeaderInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
     // リクエストに設定されている RequireAuthorizationTag タグを取得する.
        // もしタグが設定されていなければ tag は null となる.
        val tag = request.tag(RequireAuthorizationTag::class.java)
        return if (tag != null) {
            // タグが設定されていた場合、認証情報を設定する.
            chain.proceed(request)
                .newBuilder()
                .header("Authorization", "...")
                .build()
        } else {
            chain.proceed(request)
        }
    }
}

最後に作成した AddAuthorizationHeaderInterceptorOkHttpClient に設定します。

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(AddAuthorizationHeaderInterceptor()) // Interceptor を設定.
    .build()

Retrofit でもタグが設定できる

この機能は Retrofit でも使用することができます。

Retrofit でもリクエストごとにタグを設定することができ、その設定は @Tag アノテーションによって行います。

interface ApiService {

    @GET("...")
    fun getMyMessage(@Tag RequireAuthorizationTag tag): Message
}

これで呼び出す時に RequireAuthorizationTag を指定すればリクエストにタグが設定される状態となるので、先ほどと同じように Interceptor でタグを参照することができます。

apiService.getMyMessage(RequireAuthorizationTag)

注意点

同一の型のタグは2つ以上設定できない

リクエストごとにタグを設定することができますが、OkHttp の Request.Builder 内のコードを見るとタグの設定を保持しておくためのオブジェクトは以下のような定義になっています。

internal var tags: MutableMap<Class<*>, Any> = mutableMapOf()

キーの部分が Class<*> になっているため、同一の型のタグを2つ以上設定することができません

また Retrofit で同一の型のタグが2つ以上設定されている場合、実行時に例外を投げるので注意してください

設定するタグの型について

先ほど紹介した例の中では、以下のようにタグ用のオブジェクトを作り、それをタグとして設定しています。

object RequireAuthorizationTag

タグには Boolean などのプリミティブ型の指定も可能です。

しかし、上記のようにオブジェクトを作った方が意味のある名前にできてコードが見やすくなると私は思っています。

最後に

OkHttp のタグ機能を紹介しました。

この記事がどなたかのお役に立てれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0