-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve the customizable HttpClient configuration
- Loading branch information
1 parent
817b551
commit b183408
Showing
18 changed files
with
357 additions
and
220 deletions.
There are no files selected for viewing
128 changes: 80 additions & 48 deletions
128
tmdb-api/src/commonMain/kotlin/app/moviebase/tmdb/Tmdb3.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,85 @@ | ||
package app.moviebase.tmdb | ||
|
||
import app.moviebase.tmdb.api.* | ||
import app.moviebase.tmdb.remote.TmdbHttpClientFactory | ||
import app.moviebase.tmdb.remote.TmdbLogLevel | ||
import app.moviebase.tmdb.remote.TmdbSessionProvider | ||
import io.ktor.client.* | ||
|
||
class Tmdb3( | ||
tmdbApiKey: String, | ||
logLevel: TmdbLogLevel = TmdbLogLevel.NONE, | ||
tmdbSessionProvider: TmdbSessionProvider? = null, | ||
httpClientConfigBlock: (HttpClientConfig<*>.() -> Unit)? = null, | ||
) { | ||
private val client: HttpClient = TmdbHttpClientFactory.create( | ||
tmdbApiKey = tmdbApiKey, | ||
logLevel = logLevel, | ||
httpClientConfigBlock = httpClientConfigBlock, | ||
) | ||
private val clientWithSession: HttpClient = TmdbHttpClientFactory.createWithSession( | ||
tmdbApiKey = tmdbApiKey, | ||
logLevel = logLevel, | ||
tmdbSessionProvider = tmdbSessionProvider, | ||
httpClientConfigBlock = httpClientConfigBlock, | ||
) | ||
|
||
val account = TmdbAccountApi(clientWithSession) | ||
val authentication = TmdbAuthenticationApi(client) | ||
val certifications = TmdbCertificationsApi(client) | ||
val changes = TmdbChangesApi(client) | ||
val collections = TmdbCollectionsApi(client) | ||
val companies = TmdbCompaniesApi(client) | ||
val configuration = TmdbConfigurationApi(client) | ||
val credits = TmdbCreditsApi(client) | ||
val discover = TmdbDiscoverApi(client) | ||
val find = TmdbFindApi(client) | ||
val genres = TmdbGenresApi(client) | ||
val guestSessions = TmdbGuestSessionsApi(client) | ||
val keywords = TmdbKeywordsApi(client) | ||
val lists = TmdbListsApi(client) | ||
val movies = TmdbMoviesApi(client) | ||
val networks = TmdbNetworksApi(client) | ||
val trending = TmdbTrendingApi(client) | ||
val people = TmdbPeopleApi(client) | ||
val reviews = TmdbReviewsApi(client) | ||
val search = TmdbSearchApi(client) | ||
val show = TmdbShowApi(client) | ||
val showSeasons = TmdbShowSeasonsApi(client) | ||
val showEpisodes = TmdbShowEpisodesApi(client) | ||
val showEpisodeGroups = TmdbShowEpisodeGroupsApi(client) | ||
import app.moviebase.tmdb.api.TmdbAccountApi | ||
import app.moviebase.tmdb.api.TmdbAuthenticationApi | ||
import app.moviebase.tmdb.api.TmdbCertificationsApi | ||
import app.moviebase.tmdb.api.TmdbChangesApi | ||
import app.moviebase.tmdb.api.TmdbCollectionsApi | ||
import app.moviebase.tmdb.api.TmdbCompaniesApi | ||
import app.moviebase.tmdb.api.TmdbConfigurationApi | ||
import app.moviebase.tmdb.api.TmdbCreditsApi | ||
import app.moviebase.tmdb.api.TmdbDiscoverApi | ||
import app.moviebase.tmdb.api.TmdbFindApi | ||
import app.moviebase.tmdb.api.TmdbGenresApi | ||
import app.moviebase.tmdb.api.TmdbGuestSessionsApi | ||
import app.moviebase.tmdb.api.TmdbKeywordsApi | ||
import app.moviebase.tmdb.api.TmdbListsApi | ||
import app.moviebase.tmdb.api.TmdbMoviesApi | ||
import app.moviebase.tmdb.api.TmdbNetworksApi | ||
import app.moviebase.tmdb.api.TmdbPeopleApi | ||
import app.moviebase.tmdb.api.TmdbReviewsApi | ||
import app.moviebase.tmdb.api.TmdbSearchApi | ||
import app.moviebase.tmdb.api.TmdbShowApi | ||
import app.moviebase.tmdb.api.TmdbShowEpisodeGroupsApi | ||
import app.moviebase.tmdb.api.TmdbShowEpisodesApi | ||
import app.moviebase.tmdb.api.TmdbShowSeasonsApi | ||
import app.moviebase.tmdb.api.TmdbTrendingApi | ||
import app.moviebase.tmdb.remote.TmdbDsl | ||
import app.moviebase.tmdb.remote.buildHttpClient | ||
import app.moviebase.tmdb.remote.interceptRequest | ||
import io.ktor.client.HttpClient | ||
import io.ktor.client.request.* | ||
|
||
@TmdbDsl | ||
fun Tmdb3(block: TmdbClientConfig.() -> Unit): Tmdb3 { | ||
val config = TmdbClientConfig().apply(block) | ||
return Tmdb3(config) | ||
} | ||
|
||
class Tmdb3 internal constructor(private val config: TmdbClientConfig) { | ||
|
||
constructor(tmdbApiKey: String) : this(TmdbClientConfig.buildDefault(tmdbApiKey)) | ||
|
||
init { | ||
requireNotNull(config.tmdbApiKey) { | ||
"TMDB API key unavailable. Set the tmdbApiKey field in the class TmdbClientConfig when instantiate the TMDB client." | ||
} | ||
} | ||
|
||
private val client: HttpClient by lazy { | ||
buildHttpClient(TmdbVersion.V3, config).interceptRequest { | ||
it.parameter(TmdbUrlParameter.API_KEY, config.tmdbApiKey) | ||
|
||
config.tmdbCredentials?.sessionIdProvider?.get()?.let { sessionId -> | ||
it.parameter(TmdbUrlParameter.SESSION_ID, sessionId) | ||
} | ||
} | ||
} | ||
|
||
val account: TmdbAccountApi by buildApi(::TmdbAccountApi) | ||
val authentication by buildApi(::TmdbAuthenticationApi) | ||
val certifications by buildApi(::TmdbCertificationsApi) | ||
val changes by buildApi(::TmdbChangesApi) | ||
val collections by buildApi(::TmdbCollectionsApi) | ||
val companies by buildApi(::TmdbCompaniesApi) | ||
val configuration by buildApi(::TmdbConfigurationApi) | ||
val credits by buildApi(::TmdbCreditsApi) | ||
val discover by buildApi(::TmdbDiscoverApi) | ||
val find by buildApi(::TmdbFindApi) | ||
val genres by buildApi(::TmdbGenresApi) | ||
val guestSessions by buildApi(::TmdbGuestSessionsApi) | ||
val keywords by buildApi(::TmdbKeywordsApi) | ||
val lists by buildApi(::TmdbListsApi) | ||
val movies by buildApi(::TmdbMoviesApi) | ||
val networks by buildApi(::TmdbNetworksApi) | ||
val trending by buildApi(::TmdbTrendingApi) | ||
val people by buildApi(::TmdbPeopleApi) | ||
val reviews by buildApi(::TmdbReviewsApi) | ||
val search by buildApi(::TmdbSearchApi) | ||
val show by buildApi(::TmdbShowApi) | ||
val showSeasons by buildApi(::TmdbShowSeasonsApi) | ||
val showEpisodes by buildApi(::TmdbShowEpisodesApi) | ||
val showEpisodeGroups by buildApi(::TmdbShowEpisodeGroupsApi) | ||
|
||
private fun <T> buildApi(builder: (HttpClient) -> T) = lazy { builder(client) } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
tmdb-api/src/commonMain/kotlin/app/moviebase/tmdb/TmdbClientConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package app.moviebase.tmdb | ||
|
||
import app.moviebase.tmdb.remote.TmdbDsl | ||
import io.ktor.client.* | ||
import io.ktor.client.engine.* | ||
|
||
@TmdbDsl | ||
class TmdbClientConfig { | ||
|
||
var tmdbApiKey: String? = null | ||
var tmdbAuthenticationToken: String? = null | ||
internal var tmdbCredentials: TmdbCredentials? = null | ||
|
||
var useCache: Boolean = false | ||
var useTimeout: Boolean = false | ||
var maxRetriesOnException: Int? = null | ||
|
||
internal var httpClientConfigBlock: HttpClientConfigExecution<*>? = null | ||
internal var httpClientBuilder: (() -> HttpClient)? = null | ||
|
||
fun tmdbAccountCredentials(block: TmdbCredentials.() -> Unit) { | ||
tmdbCredentials = TmdbCredentials().apply(block) | ||
} | ||
|
||
/** | ||
* Set custom HttpClient configuration for the default HttpClient. | ||
*/ | ||
fun httpClient(block: HttpClientConfigExecution<*>) { | ||
this.httpClientConfigBlock = block | ||
} | ||
|
||
/** | ||
* Creates an custom [HttpClient] with the specified [HttpClientEngineFactory] and optional [block] configuration. | ||
* Note that the TMDB config will be added afterwards. | ||
*/ | ||
fun <T : HttpClientEngineConfig> httpClient( | ||
engineFactory: HttpClientEngineFactory<T>, | ||
block: HttpClientConfigExecution<T> = {} | ||
) { | ||
httpClientBuilder = { | ||
HttpClient(engineFactory, block) | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
internal fun buildDefault( | ||
tmdbApiKey: String, | ||
tmdbAuthenticationToken: String? = null | ||
) = TmdbClientConfig().apply { | ||
this.tmdbApiKey = tmdbApiKey | ||
this.tmdbAuthenticationToken = tmdbAuthenticationToken | ||
} | ||
} | ||
} | ||
|
||
@TmdbDsl | ||
class TmdbCredentials { | ||
|
||
internal var sessionIdProvider: TmdbCredentialProvider? = null | ||
internal var accessTokenProvider: TmdbCredentialProvider? = null | ||
internal var requestTokenProvider: TmdbCredentialProvider? = null | ||
|
||
fun sessionId(provider: TmdbCredentialProvider) { | ||
sessionIdProvider = provider | ||
} | ||
|
||
fun accessToken(provider: TmdbCredentialProvider) { | ||
accessTokenProvider = provider | ||
} | ||
|
||
fun requestToken(provider: TmdbCredentialProvider) { | ||
requestTokenProvider = provider | ||
} | ||
} | ||
|
||
@TmdbDsl | ||
fun interface TmdbCredentialProvider { | ||
fun get(): String? | ||
} | ||
|
||
@TmdbDsl | ||
typealias HttpClientConfigExecution<T> = HttpClientConfig<T>.() -> Unit |
18 changes: 12 additions & 6 deletions
18
tmdb-api/src/commonMain/kotlin/app/moviebase/tmdb/TmdbWebConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,26 @@ | ||
package app.moviebase.tmdb | ||
|
||
object TmdbWebConfig { | ||
|
||
internal object TmdbWebConfig { | ||
const val BASE_URL_TMDB = "https://api.themoviedb.org" | ||
const val WEBSITE_BASE_URL = "https://www.themoviedb.org" | ||
|
||
const val VERSION_PATH_V3 = "3" | ||
const val VERSION_PATH_V4 = "4" | ||
const val BASE_URL_TMDB_IMAGE = "https://image.tmdb.org/t/p/" | ||
const val BASE_URL_YOUTUBE_IMAGE = "https://img.youtube.com/vi" | ||
const val LOGO_FILTER = "_filter(negate,000,666)" | ||
|
||
const val VERSION_PATH_V3 = "3" | ||
const val VERSION_PATH_V4 = "4" | ||
|
||
const val LOGO_FILTER = "_filter(negate,000,666)" | ||
} | ||
|
||
object TmdbUrlParameter { | ||
internal object TmdbUrlParameter { | ||
const val API_KEY = "api_key" | ||
const val SESSION_ID = "session_id" | ||
const val ACCESS_TOKEN = "access_token" | ||
} | ||
|
||
enum class TmdbVersion(val path: String) { | ||
V3(TmdbWebConfig.VERSION_PATH_V3), | ||
V4(TmdbWebConfig.VERSION_PATH_V4) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.