728x90

헤더 요청 방식

헤더 요청 방식 형태의 예 

interface SearchService {
    @Headers("Authorization: KakaoAK ${REST_API_KEY}")
    @GET("image")
    suspend fun searchImage(@Query("query") query: String): ImageListResponse
   
    @Headers("Authorization: KakaoAK ${REST_API_KEY}")
    @GET("vclip")
    suspend fun searchVideo(@Query("query") query: String): VideoListResponse
}

 

이런 형태의 요청을 OkHttpClient를 생성할 때 addInterceptor에 추가해주면 된다. 

class HeaderInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain
            .request()
            .newBuilder()
            .addHeader("Authorization", "KakaoAK ${REST_API_KEY}")
            .build()
        return chain.proceed(request)
    }
}

 

RetrofitManager 오브젝트 

object RetrofitManager {
    private val okhttpClient by lazy {
        OkHttpClient
            .Builder()
            .readTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .connectTimeout(5, TimeUnit.SECONDS)
            .addInterceptor(HeaderInterceptor())  //header 삽입// 
            .build()
    }
    private val gson by lazy {
        GsonBuilder()
            .setLenient()
            .setDateFormat("yyyy-MM-dd'T':HH:mm:ss.SSSXXX")
            .create()
    }
    private val retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okhttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build()
    }
    val searchService: SearchService by lazy { retrofit.create(SearchService::class.java) }

    class HeaderInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain
                .request()
                .newBuilder()
                .addHeader("Authorization", "KakaoAK ${REST_API_KEY}")
                .build()
            return chain.proceed(request)
        }
    }
}

 


쿼리 요청 방식 

쿼리 요청 방식 형태의 예 

interface FetchRemoteDatasource {
    @GET("pblprfr")
    suspend fun fetchShowList(
        @Query("service") service:String = KOPIS_API_KEY
        @Query("stdate") stdate: String,
        @Query("eddate") eddate: String,
        @Query("cpage") cpage: String = Constants.CURRENT_PAGE,
        @Query("rows") rows: String = Constants.PAGE_INDEX,
        @Query("openrun") openrun: String? = null,
        @Query("newsql") newsql: String? = "Y",
        @Query("shcate") shcate: String? = null,
        @Query("kidstate") kidstate: String? = null,
        @Query("prfstate") prfstate: String? = null,
    ): DbsResponse

    @GET("boxoffice")
    suspend fun fetchTopRank(
        @Query("service") service:String = KOPIS_API_KEY
        @Query("ststype") ststype: String,
        @Query("date") date: String = Converter.nowDateOneDayAgo()
        @Query("catecode") catecode: String? = null,
        @Query("area") area: String? = null,
        @Query("newsql") newsql: String? = "Y",
    ): BoxOfsResponse

}

 

쿼리 요청방식은 헤더를 추가하는 방식과 약간 다름 

addQureyParameter로 쿼리 파라미터를 추가해줌 

//Class 형태 
class ApiKeyInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val originalHttpUrl = originalRequest.url
        val url =
            originalHttpUrl.newBuilder().addQueryParameter("service", KOPIS_API_KEY).build()
        val request = originalRequest.newBuilder().url(url).build()
        return chain.proceed(request)
    }
}

//변수 형태
private val apiKeyInterceptor = Interceptor { chain ->
    val originalRequest = chain.request()
    val originalHttpUrl = originalRequest.url
    val url = originalHttpUrl.newBuilder().addQueryParameter("service", KOPIS_API_KEY).build()
    val request = originalRequest.newBuilder().url(url).build()
    chain.proceed(request)
}

 

마찬가지로, OkHttpClient를 생성할 때 addInterceptor로 추가

object RetrofitClient {
    // API Key 삽입을 위한 인터셉터
    //class 형태 
    class ApiKeyInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            val originalRequest = chain.request()
            val originalHttpUrl = originalRequest.url
            val url =
                originalHttpUrl.newBuilder().addQueryParameter("service", KOPIS_API_KEY).build()
            val request = originalRequest.newBuilder().url(url).build()
            return chain.proceed(request)
        }
    }
	//변수 형태
    private val apiKeyInterceptor = Interceptor { chain ->
        val originalRequest = chain.request()
        val originalHttpUrl = originalRequest.url
        val url = originalHttpUrl.newBuilder().addQueryParameter("service", KOPIS_API_KEY).build()
        val request = originalRequest.newBuilder().url(url).build()
        chain.proceed(request)
    }

    // OkHttpClient 설정
    private val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(apiKeyInterceptor) // 또는 ApiKeyInterceptor() 
        .readTimeout(15, TimeUnit.SECONDS)
        .writeTimeout(15, TimeUnit.SECONDS)
        .connectTimeout(15, TimeUnit.SECONDS)
        .build()

    // Retrofit 설정
    private val retrofit: Retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .build()
    }

    val fetch: FetchRemoteDatasource by lazy { retrofit.create(FetchRemoteDatasource::class.java) }
    val search: SearchRemoteDatasource by lazy { retrofit.create(SearchRemoteDatasource::class.java) }
}

 

 

두 코드 모두 동일한 기능을 수행하지만, 클래스 형태가 가독성과 재사용성 측면에서 조금 더 나을 수 있음

  • 가독성 : 클래스 형태는 코드의 구조가 명확하고 가독성이 높다.
  • 재사용성 : 클래스 형태는 다른 곳에서 재사용하기 용이하다.
  • 간결성: 변수 형태는 람다 표현식을 사용하여 간결하게 Interceptor를 구현할 수 있다.



 

+ Recent posts