Skip to content

Commit

Permalink
fix: do not require List<Client*Interceptor> to be bound when using T…
Browse files Browse the repository at this point in the history
…ypedClientFactory stand-alone (cashapp#2218)

When an app does not use TypedHttpClientModule and tries to use TypedClientFactory, it asks for lists of client interceptors. These are usually bound to an empty list (new multibinder) in TypedHttpClientModule, so without that module bound it fails.
  • Loading branch information
r3mariano authored Nov 17, 2021
1 parent 302e725 commit 8524995
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
14 changes: 8 additions & 6 deletions misk/src/main/kotlin/misk/client/TypedHttpClientModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,15 @@ class TypedClientFactory @Inject constructor() {
// Use Providers for the interceptors so Guice can properly detect cycles when apps inject
// an HTTP Client in an Interceptor.
// https://gist.github.com/ryanhall07/e3eac6d2d47b72a4c37bce87219d7ced
@Inject
private lateinit var clientNetworkInterceptorFactories:
Provider<List<ClientNetworkInterceptor.Factory>>
// Also, these are optional because the end user may not have used TypedHttpClientModule at all
// and thus may not have had multibindings provided here.
@Inject(optional = true)
private val clientNetworkInterceptorFactories:
Provider<List<ClientNetworkInterceptor.Factory>> = Provider { emptyList() }

@Inject
private lateinit var clientApplicationInterceptorFactories:
Provider<List<ClientApplicationInterceptorFactory>>
@Inject(optional = true)
private val clientApplicationInterceptorFactories:
Provider<List<ClientApplicationInterceptorFactory>> = Provider { emptyList() }

@Inject
private lateinit var clientMetricsInterceptorFactory: ClientMetricsInterceptor.Factory
Expand Down
12 changes: 12 additions & 0 deletions misk/src/test/kotlin/misk/client/TypedHttpClientTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ internal class TypedHttpClientTest {
fun buildDynamicClients() {
val typedClientFactory = clientInjector.getInstance(TypedClientFactory::class.java)

testBuildAndUseDynamicClient(typedClientFactory)
}

@Test
fun buildDynamicClientWithoutHavingBuiltAnyOtherClients() {
val injector = Guice.createInjector(MiskTestingServiceModule())
val typedClientFactory = injector.getInstance(TypedClientFactory::class.java)

testBuildAndUseDynamicClient(typedClientFactory)
}

private fun testBuildAndUseDynamicClient(typedClientFactory: TypedClientFactory) {
val dinoClient = typedClientFactory.build<ReturnADinosaur>(
HttpClientEndpointConfig(jetty.httpServerUrl.toString()),
"dynamicDino"
Expand Down

0 comments on commit 8524995

Please sign in to comment.