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)
}
}
}
最後に作成した AddAuthorizationHeaderInterceptor
を OkHttpClient
に設定します。
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 のタグ機能を紹介しました。
この記事がどなたかのお役に立てれば幸いです。