Skip to content

Commit

Permalink
COINS-2255 | Refactor creating Retrofit services (#17)
Browse files Browse the repository at this point in the history
* COINS-2255 | Refactor creating Retrofit services

OkHttpClient instance is no longer created in this library. It has to be passed from the outside. Thanks to this change the OkHttpClient can be shared with the rest of the app.

* COINS-2255 | Bump library version to 0.4.4
  • Loading branch information
bartek-wesolowski authored Feb 27, 2021
1 parent 7fe9719 commit 062141b
Show file tree
Hide file tree
Showing 15 changed files with 58 additions and 123 deletions.
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ repositories {
apply from: 'buildsystem/ci.gradle'
apply from: 'buildsystem/dependencies.gradle'

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}

dependencies {
implementation apiDependencies.kotlinJdk
implementation apiDependencies.kotlinCoroutines
Expand Down
2 changes: 1 addition & 1 deletion buildsystem/ci.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ext {
siteUrl = 'https://github.com/coinpaprika/coinpaprika-api-kotlin-client'
gitUrl = 'https://github.com/coinpaprika/coinpaprika-api-kotlin-client.git'

libraryVersion = '0.4.3'
libraryVersion = '0.4.4'

developerId = 'coinpaprika'
developerName = 'CoinPaprika'
Expand Down
26 changes: 14 additions & 12 deletions src/main/java/com/coinpaprika/apiclient/api/CoinpaprikaApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ import com.coinpaprika.apiclient.repository.search.SearchApi
import com.coinpaprika.apiclient.repository.tag.TagApi
import com.coinpaprika.apiclient.repository.ticker.TickerApi
import io.reactivex.Observable

open class CoinpaprikaApi {

private var tickerApi = TickerApi()
private var coinApi = CoinApi()
private var tagApi = TagApi()
private var peopleApi = PeopleApi()
private var searchApi = SearchApi()
private var newsApi = NewsApi()
private var rankingApi = RankingApi()
private var globalApi = GlobalApi()
private var fiatApi = FiatApi()
import retrofit2.Retrofit
import retrofit2.create

open class CoinpaprikaApi(retrofit: Retrofit) {

private var tickerApi = TickerApi(retrofit.create())
private var coinApi = CoinApi(retrofit.create())
private var tagApi = TagApi(retrofit.create())
private var peopleApi = PeopleApi(retrofit.create())
private var searchApi = SearchApi(retrofit.create())
private var newsApi = NewsApi(retrofit.create())
private var rankingApi = RankingApi(retrofit.create())
private var globalApi = GlobalApi(retrofit.create())
private var fiatApi = FiatApi(retrofit.create())

suspend fun ticker(id: String, quotes: String? = null): TickerEntity {
return tickerApi.getTicker(id, quotes)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
/*
* Created by Piotr Kostecki on 5/16/19 4:05 PM
*/

package com.coinpaprika.apiclient.api

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.Protocol
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit


fun defaultClient(): OkHttpClient.Builder {
return OkHttpClient.Builder()
.protocols(listOf(Protocol.HTTP_1_1, Protocol.HTTP_2))
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.connectionPool(ConnectionPool(0, 1, TimeUnit.NANOSECONDS))
}

class CoinpaprikaApiFactory(private val client: OkHttpClient = defaultClient().build()) {
companion object {
private const val BASE_URL = "https://api.coinpaprika.com/v1/"
}

fun client(): Retrofit {
object CoinpaprikaApiFactory {
fun getRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.baseUrl("https://api.coinpaprika.com/v1/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
Expand Down
21 changes: 8 additions & 13 deletions src/main/java/com/coinpaprika/apiclient/repository/coin/CoinApi.kt
Original file line number Diff line number Diff line change
@@ -1,42 +1,37 @@
package com.coinpaprika.apiclient.repository.coin

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.*
import com.coinpaprika.apiclient.extensions.safeApiCallRaw
import io.reactivex.Observable
import retrofit2.Response

class CoinApi constructor(
private var retrofit: CoinApiContract = CoinpaprikaApiFactory()
.client()
.create(CoinApiContract::class.java)
) : CoinApiContract {
class CoinApi(private var contract: CoinApiContract) : CoinApiContract {

override suspend fun getCoin(id: String): CoinDetailsEntity {
return retrofit.getCoin(id)
return contract.getCoin(id)
}

override suspend fun getCoins(additionalFields: String?): List<CoinEntity> {
return retrofit.getCoins(additionalFields)
return contract.getCoins(additionalFields)
}

override fun getEvents(id: String): Observable<Response<List<EventEntity>>> {
return safeApiCallRaw { retrofit.getEvents(id) }
return safeApiCallRaw { contract.getEvents(id) }
}

override fun getExchanges(id: String): Observable<Response<List<ExchangeEntity>>> {
return safeApiCallRaw { retrofit.getExchanges(id) }
return safeApiCallRaw { contract.getExchanges(id) }
}

override fun getMarkets(id: String, quotes: String): Observable<Response<List<MarketEntity>>> {
return safeApiCallRaw { retrofit.getMarkets(id, quotes) }
return safeApiCallRaw { contract.getMarkets(id, quotes) }
}

override fun getTweets(id: String): Observable<Response<List<TweetEntity>>> {
return safeApiCallRaw { retrofit.getTweets(id) }
return safeApiCallRaw { contract.getTweets(id) }
}

override fun addEvent(cryptoId: String, event: EventEntity): Observable<Response<Void>> {
return safeApiCallRaw { retrofit.addEvent(cryptoId, event) }
return safeApiCallRaw { contract.addEvent(cryptoId, event) }
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
package com.coinpaprika.apiclient.repository.exchange

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.ExchangeEntity
import com.coinpaprika.apiclient.entity.MarketEntity
import com.coinpaprika.apiclient.extensions.safeApiCallRaw
import io.reactivex.Observable
import retrofit2.Response

class ExchangeApi constructor(
private var retrofit: ExchangeApiContract = CoinpaprikaApiFactory()
.client()
.create(ExchangeApiContract::class.java)
) : ExchangeApiContract {
class ExchangeApi(private var contract: ExchangeApiContract) : ExchangeApiContract {

override fun getExchanges(): Observable<Response<List<ExchangeEntity>>> {
return safeApiCallRaw { retrofit.getExchanges() }
return safeApiCallRaw { contract.getExchanges() }
}

override fun getMarkets(exchangeId: String): Observable<Response<List<MarketEntity>>> {
return safeApiCallRaw { retrofit.getMarkets(exchangeId) }
return safeApiCallRaw { contract.getMarkets(exchangeId) }
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package com.coinpaprika.apiclient.repository.fiats

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.FiatEntity

class FiatApi constructor(
private var retrofit: FiatApiContract = CoinpaprikaApiFactory()
.client()
.create(FiatApiContract::class.java)
) : FiatApiContract {
class FiatApi(private var contract: FiatApiContract) : FiatApiContract {

override suspend fun getFiats(): List<FiatEntity> {
return retrofit.getFiats()
return contract.getFiats()
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package com.coinpaprika.apiclient.repository.global

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.GlobalStatsEntity
import com.coinpaprika.apiclient.extensions.safeApiCallRaw
import io.reactivex.Observable
import retrofit2.Response

class GlobalApi constructor(
private var retrofit: GlobalApiContract = CoinpaprikaApiFactory()
.client()
.create(GlobalApiContract::class.java)
) : GlobalApiContract {
class GlobalApi(private var contract: GlobalApiContract) : GlobalApiContract {

override fun getGlobal(): Observable<Response<GlobalStatsEntity>> {
return safeApiCallRaw { retrofit.getGlobal() }
return safeApiCallRaw { contract.getGlobal() }
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package com.coinpaprika.apiclient.repository.news

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.NewsEntity
import com.coinpaprika.apiclient.extensions.safeApiCallRaw
import io.reactivex.Observable
import retrofit2.Response

class NewsApi constructor(
private var retrofit: NewsApiContract = CoinpaprikaApiFactory()
.client()
.create(NewsApiContract::class.java)
) : NewsApiContract {
class NewsApi(private var contract: NewsApiContract) : NewsApiContract {

override fun getNews(limit: Int): Observable<Response<List<NewsEntity>>> {
return safeApiCallRaw { retrofit.getNews(limit) }
return safeApiCallRaw { contract.getNews(limit) }
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
package com.coinpaprika.apiclient.repository.people

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.PersonEntity
import com.coinpaprika.apiclient.entity.TweetEntity
import com.coinpaprika.apiclient.extensions.safeApiCallRaw
import io.reactivex.Observable
import retrofit2.Response

class PeopleApi constructor(
private var retrofit: PeopleApiContract = CoinpaprikaApiFactory()
.client()
.create(PeopleApiContract::class.java)
) : PeopleApiContract {
class PeopleApi(private var contract: PeopleApiContract) : PeopleApiContract {

override fun getPerson(id: String): Observable<Response<PersonEntity>> {
return safeApiCallRaw { retrofit.getPerson(id) }
return safeApiCallRaw { contract.getPerson(id) }
}

override fun getTweets(id: String): Observable<Response<List<TweetEntity>>> {
return safeApiCallRaw { retrofit.getTweets(id) }
return safeApiCallRaw { contract.getTweets(id) }
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package com.coinpaprika.apiclient.repository.ranking

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.TopMoversEntity

class RankingApi constructor(
private var retrofit: RankingApiContract = CoinpaprikaApiFactory()
.client()
.create(RankingApiContract::class.java)
) : RankingApiContract {
class RankingApi(private var contract: RankingApiContract) : RankingApiContract {

override suspend fun getTop10Movers(type: String): TopMoversEntity {
return retrofit.getTop10Movers(type)
return contract.getTop10Movers(type)
}

override suspend fun getMovers(results: Int, range: String): TopMoversEntity {
return retrofit.getMovers(results, range)
return contract.getMovers(results, range)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@

package com.coinpaprika.apiclient.repository.search

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.SearchEntity

class SearchApi constructor(
private var retrofit: SearchApiContract = CoinpaprikaApiFactory()
.client()
.create(SearchApiContract::class.java)
) : SearchApiContract {
class SearchApi(private var contract: SearchApiContract) : SearchApiContract {

override suspend fun getSearches(query: String): SearchEntity {
return retrofit.getSearches(query)
return contract.getSearches(query)
}
}
11 changes: 3 additions & 8 deletions src/main/java/com/coinpaprika/apiclient/repository/tag/TagApi.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package com.coinpaprika.apiclient.repository.tag

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.TagEntity

class TagApi constructor(
private var retrofit: TagApiContract = CoinpaprikaApiFactory()
.client()
.create(TagApiContract::class.java)
) : TagApiContract {
class TagApi(private var contract: TagApiContract) : TagApiContract {

override suspend fun getTag(id: String): TagEntity {
return retrofit.getTag(id)
return contract.getTag(id)
}

override suspend fun getTags(): List<TagEntity> {
return retrofit.getTags()
return contract.getTags()
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
package com.coinpaprika.apiclient.repository.ticker

import com.coinpaprika.apiclient.api.CoinpaprikaApiFactory
import com.coinpaprika.apiclient.entity.TickerEntity
import com.coinpaprika.apiclient.extensions.handleCall

class TickerApi {

private var retrofit: TickerApiContract = CoinpaprikaApiFactory()
.client()
.create(TickerApiContract::class.java)
class TickerApi(private val contract: TickerApiContract) {

suspend fun getTicker(id: String, quotes: String? = null): TickerEntity {
return handleCall {
if (quotes != null) {
retrofit.getTicker(id, quotes)
contract.getTicker(id, quotes)
} else {
retrofit.getTicker(id)
contract.getTicker(id)
}
}
}

suspend fun getTickers(quotes: String? = null): List<TickerEntity> {
return handleCall {
if (quotes != null) {
retrofit.getTickers(quotes)
contract.getTickers(quotes)
} else {
retrofit.getTickers()
contract.getTickers()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.coinpaprika.apiclient.repository.ticker

import com.coinpaprika.apiclient.entity.TickerEntity
import io.reactivex.Observable
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

internal interface TickerApiContract {
interface TickerApiContract {
@GET("tickers/{id}/")
suspend fun getTicker(@Path("id") id: String, @Query("quotes") quotes: String = "USD,BTC,ETH,PLN"): Response<TickerEntity>

Expand Down

0 comments on commit 062141b

Please sign in to comment.