If I'm using dagger/hilt and I have a bunch of gra...
# dagger
c
If I'm using dagger/hilt and I have a bunch of gradle modules. And each gradle module provides their own OkhttpInterceptor for example, is it possible to grab all available objects of that type and add them all to okhttps interceptor list?
Note that the order for interceptors matters. Multibindings does not provide any order guarantees.
c
Oof. I wonder if there's any way around that.
Thanks though. I forgot that multibindings were the name for that. lets see if that actually helps me out in my situation. cheers
Maybe I can provide
Interceptor
types, but I can maybe check to see what concrete type it actually is... and if it's something important where ordering matters, then I can re-order it by hand before i pass it into my okhttp client in the app module.
e
you could always add some decoration around it, e.g.
Copy code
data class PrioritizedInterceptor(
    val priority: Int,
    val interceptor: Interceptor,
)
@[Provides IntoSet] fun first() = PrioritizedInterceptor(0, OuterInterceptor)
@[Provides IntoSet] fun last() = PrioritizedInterceptor(Int.MAX_VALUE, InnerInterceptor)
@Inject constructor(interceptors: Set<@JvmSuppressWildcards PrioritizedInterceptor>) {
    for ((_, interceptor) in interceptors.sortedBy { it.priority }) {
        addInterceptor(interceptor)
c
My current solution kinda defeats the purpose maybe of having these interceptors in separate modules, but just using @Named("blah") Interceptor seems to get the job done for my scenario here. multi modules, dependency graph, etc makes my head hurt
@ephemient very nice little wrapper
FWIW. My use case right now is actually that for whatever reason I have two http clients in two separate modules. and i want to share one interceptor from module1 to module2, but i dont want module2 to depend on module1. I feel like my solutions are: 1. create a seperate module with these interceptors, and module1 and module2 depend on that new intercept-module 2. Provide the module 1 interceptor (either by multi binding or a @Named) and grab the interceptor from module2 that way
e
usually creating multiple OkHttpClients is a bad thing
https://square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/ hmm, the formatting was nicer in the old javadocs…
c
Yeah. We know the multiple okhttp clients is "bad" but we're in the midst of killing 1. For the time being we just need this as a temporary layer. I guess I can revisit sharing a single okhttp client as then I wouldn't have to repeat interceptors and such.
Actually. I don't think we can share okhttp clients since the new http client needs an additional header.
e
use
newBuilder()
from the shared client, it'll let you build a new instance while sharing the executor etc. (as the docs say)
c
ooooh.
lazy meme. replace the text with "is this my solution?" lmaoo
@ephemient i think that pretty much works perfect. So I'm just going to share my http client from module1 to 2 using a named qualifier. then just add my one extra intercept/header via newBuilder() CLUTCH
d
That's what we do. We have a single OkHttpClient in our app that every other client ultimately creates itself from using newBuilder(). It works really nicely and it recycles the thread pool under the hood. Here's the talk I learned it from: https://m.youtube.com/watch?v=t34AQlblSeE
c
@Daniel Perez thanks for the link and @jw thanks for the presentation. that was awesome. so many cool little tricks i wanna implement now. cheers both
d
It's a fire talk that holds up pretty well
c
pretty much expalined my use case directly. a "base" okhttp client, and then i can add a few more interceptors for whichever service i need.
holds up very well! And I still agree that jake should update u2020 even 6 years later. lmao and i guess the whole retrofit interceptor thing never came to be. lol
u
Yea I was about to say what others did, built the priority into the registered type i.e.
Priority(1, FooInterceptor())