Skip to content

Instantly share code, notes, and snippets.

View naturalwarren's full-sized avatar
🎯
Focusing

Warren Smith naturalwarren

🎯
Focusing
View GitHub Profile
{
"securities":{
"security":[
{
"symbol":"PHYS",
"exchange":"Q",
"type":"stock",
"description":"Sprott Physical Gold Trust ETV"
}
]
/**
* Indicates an endpoint wraps a response in a JSON Object.
* When deserializing the response we should only return
* what's inside the outer most object.
*/
@Retention(RUNTIME)
@JsonQualifier
@Target(FUNCTION, CLASS)
internal annotation class Enveloped
/**
* Complements @Enveloped by performing custom deserialization
* for a response that is wrapped in a JSON Object.
*/
internal class EnvelopeFactory : JsonAdapter.Factory {
companion object {
val INSTANCE = EnvelopeFactory()
}
override fun create(
interface TradierApi {
@Enveloped
@GET("markets/lookup")
fun lookup(@Query("q") symbol: String): Single<Securities>
}
@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()
@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 {
@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 {
@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 / 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 / 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())
}