I am developing a simple app to fetch now playing movie details from https://www.themoviedb.org/ API. This is the URL to which I need to perform the API call.
https://api.themoviedb.org/3/movie/now_playing?api_key=<<api_key>>
I am using retrofit to make the API call like this.
@GET("/movie/now_playing")
fun getNowPlayingMovies(): Single<List<MovieData>>
and I am using Base Url and API key as variables in the client class.
private val BASE_URL = "https://api.themoviedb.org/3/"
private val API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
Since the best way to add the api key as a query parameter to the URL is by using a request Interceptor , I created an intercepted to intercept the request and add the api key as a query parameter.
private fun getInterceptor() : Interceptor{
if (requestInterceptor == null){
requestInterceptor = Interceptor{
val url = it.request()
.url
.newBuilder()
.addQueryParameter("api_key" , API_KEY)
.build()
val request = it.request()
.newBuilder()
.url(url)
.build()
return@Interceptor it.proceed(request)
}
}
return requestInterceptor
}
Then added this interceptor along with logging interceptor to the OkHttp Client.
private fun getOkHttpClient() : OkHttpClient{
var httLog : HttpLoggingInterceptor = HttpLoggingInterceptor()
httLog.setLevel(HttpLoggingInterceptor.Level.BODY)
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(getInterceptor()).addInterceptor(httLog)
.connectTimeout(60 , TimeUnit.SECONDS)
.build()
return okHttpClient
}
And then build the retrofit client. In which I add the base URL.
var retrofit : Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getOkHttpClient())
.addConverterFactory(getGsonConverterFactory())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
The problem is , the entire URL made using the BASE_URL and the api as a Query Paramter , Should be like this
https://api.themoviedb.org/3/movie/now_playing?api_key=**********
But in the logging interceptor I am getting this as the url
https://api.themoviedb.org/movie/now_playing?api_key=**********
which has a different BASE_URL than the one I provided in retrofit. It is giving me a 404 error.
I cannot seem to figure out why this is causing. I logged on different places and I believe the request Interceptor is intercepting a different URL than the BASE_URL.
This is my entire codebase, it would be very helpful if there are any other improvements in the code , I am new to android development and Kotlin. Thank You.
interface MoviesApiServiceRx {
@GET("/movie/now_playing")
fun getNowPlayingMovies(): Single<List<MovieData>>
}
class MoviesRetrofitClient() {
private val BASE_URL = "https://api.themoviedb.org/3/"
private val API_KEY = "9a976526fce8c29aaa35eb4a1e654d3c"
private var moviesApiServiceRx : MoviesApiServiceRx
private var gsonConverterFactory : GsonConverterFactory
private var requestInterceptor : Interceptor
init {
moviesApiServiceRx = getMoviesApiServiceRx()
gsonConverterFactory = getGsonConverterFactory()
requestInterceptor = getInterceptor()
}
private fun getInterceptor() : Interceptor{
if (requestInterceptor == null){
requestInterceptor = Interceptor{
val url = it.request()
.url
.newBuilder()
.addQueryParameter("api_key" , API_KEY)
.build()
val request = it.request()
.newBuilder()
.url(url)
.build()
return@Interceptor it.proceed(request)
}
}
return requestInterceptor
}
private fun getGsonConverterFactory() : GsonConverterFactory{
if (gsonConverterFactory == null){
gsonConverterFactory = GsonConverterFactory.create();
}
return gsonConverterFactory
}
private fun getOkHttpClient() : OkHttpClient{
var httLog : HttpLoggingInterceptor = HttpLoggingInterceptor()
httLog.setLevel(HttpLoggingInterceptor.Level.BODY)
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(getInterceptor()).addInterceptor(httLog)
.connectTimeout(60 , TimeUnit.SECONDS)
.build()
return okHttpClient
}
private fun getMoviesApiServiceRx() : MoviesApiServiceRx{
if (moviesApiServiceRx == null){
var retrofit : Retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getOkHttpClient())
.addConverterFactory(getGsonConverterFactory())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
moviesApiServiceRx = retrofit.create(MoviesApiServiceRx::class.java)
}
return moviesApiServiceRx
}
fun getNowPlayingMovies(): Single<List<MovieData>> {
return getMoviesApiServiceRx().
getNowPlayingMovies()
}
}
CodePudding user response:
two options
interface MoviesApiServiceRx {
@GET("/3/movie/now_playing")
fun getNowPlayingMovies(): Single<List<MovieData>>
}
private val BASE_URL = "https://api.themoviedb.org/"
or
interface MoviesApiServiceRx {
@GET("movie/now_playing")
fun getNowPlayingMovies(): Single<List<MovieData>>
}
private val BASE_URL = "https://api.themoviedb.org/3/"
CodePudding user response:
Change
@GET("/movie/now_playing")
to
@GET("movie/now_playing")
The /
at the beginning refers to the root so it will replace whatever there is after the service name.