Skip to content

Instantly share code, notes, and snippets.

View naturalwarren's full-sized avatar
🎯
Focusing

Warren Smith naturalwarren

🎯
Focusing
View GitHub Profile
/**
* A [CallAdapter.Factory] which allows [CoinbaseResponse] objects to
* be returned from RxJava streams.
*
* Adding this class to [Retrofit] allows you to return [Observable],
* [Flowable], [Single], or [Maybe] types parameterized with [CoinbaseResponse]
* from service methods. This adapter must be registered before an adapter
* that is capable of adapting RxJava streams.
*
* For the type [Observable<CoinbaseResponse<SuccessBody, ErrorBody>>],
@naturalwarren
naturalwarren / CoinbaseResponse.kt
Last active December 2, 2018 21:17
Custom response class CoinbaseResponse.
/**
* A response class that holds a success and error body type as well
* as a throwable for network errors.
*
* @param T success response body type.
* @param U error response body type.
* @param body set when a call succeeds with a 2xx status code.
* @param errorBody set when a call fails with a non-2xx calls status code.
* @param networkError set when a network error occurs.
*/
@naturalwarren
naturalwarren / CoinbaseRxJavaCallAdapterFactory.kt
Created December 2, 2018 19:33
Call Adapter that provides type safe error bodies.
/**
* A [CallAdapter.Factory] which allows [CoinbaseResponse] objects to be returned from RxJava
* streams.
*
* Adding this class to [Retrofit] allows you to return [Observable], [Flowable], [Single], or
* [Maybe] types parameterized with [CoinbaseResponse] from service methods. This adapter must be
* registered before an adapter that is capable of adapting RxJava streams.
*
* For the type [Observable<CoinbaseResponse<SuccessBody, ErrorBody>>], the following semantics are
* provided:
@naturalwarren
naturalwarren / OAuthApi.kt
Last active December 2, 2018 19:25
Demonstrates
val authApi: OAuthApi = Retrofit.newBuilder()
.baseUrl(COINBASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.build()
.create()
interface OAuthApi {
/**
@naturalwarren
naturalwarren / Api.kt
Last active January 23, 2019 22:35
Making a Retrofit API call with RxJava
authApi.getTokens()
.subscribe({ response: Response<AccessToken> ->
when {
response.isSuccessful && response.body() != null -> {
// Case 1: Success. We got a response with a body.
}
response.errorBody() != null -> {
// Case 2: Failure. We got an error from the backend, deserialize it.
val error = moshi.adapter(Error::class.java).fromJson(errorBody.source())
}
@naturalwarren
naturalwarren / AccessTokenInterceptor.kt
Last active December 2, 2018 16:22
Interceptor that authorizes requests with an access token.
class AccessTokenInterceptor(
private val tokenProvider: AccessTokenProvider
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val token = tokenProvider.token()
return if (token == null) {
chain.proceed(chain.request())
} else {
@naturalwarren
naturalwarren / AccessTokenProvider.kt
Created December 2, 2018 16:13
Contract for providing and refreshing an access token.
/**
* Provides an access token for request authorization.
*/
interface AccessTokenProvider {
/**
* Returns an access token. In the event that you don't have a token return null.
*/
fun token(): String?
@naturalwarren
naturalwarren / AccessTokenAuthenticator.kt
Last active October 30, 2023 15:14
An OkHttp Authenticator that performs token refreshes.
/**
* Authenticator that attempts to refresh the client's access token.
* In the event that a refresh fails and a new token can't be issued an error
* is delivered to the caller. This authenticator blocks all requests while a token
* refresh is being performed. In-flight requests that fail with a 401 are
* automatically retried.
*/
class AccessTokenAuthenticator(
private val tokenProvider: AccessTokenProvider
) : Authenticator {
@Module
abstract class AppModule {
@Module
companion object {
private const val HTTP_RESPONSE_CACHE = (10 * 1024 * 1024).toLong()
@AppScope @Provides @JvmStatic
fun httpClient(cache: Cache): OkHttpClient {
@Provides
fun retrofit(okHttpClient: Lazy<OkHttpClient>) = Retrofit.Builder()
.baseUrl("https://sandbox.tradier.com/v1/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.callFactory { okHttpClient.get().newCall(it) }
.build()