Stylianos Gakis
12/12/2022, 4:57 PMokhttp3.Authenticator
with it.
So my use case is as such. We use okhttp interceptors to append the Auth token on our requests, and an okhttp3.Authenticator
to respond to 401s by refreshing token, retrying the request and so on.
Thing is, apparently sometimes we get the 401 inside the graphql response with a 200 header so we can’t entirely rely on the okhttp3.Authenticator
to check these not authorized cases, but we need an okhttp interceptor on top of it to catch those cases too.
Is my best bet to simply use a com.apollographql.apollo3.interceptor.ApolloInterceptor
, look at the response body for the 401 in the error codes, and do what my okhttp3.Authenticator
would do? Is it weird that our backend responds with 200 but 401 in the error message itself? I also worry about concurrent access from both my okhttp3.Authenticator
and my com.apollographql.apollo3.interceptor.ApolloInterceptor
both trying to get the refresh token and create a new access token. I guess I’d also need to manage the concurrency by locking on whatever class they both access, instead of locking inside the two authenticators/interceptors themselves.
Just asking here to see if I am going in the right direction or if I am missing something super obvious that would make my life easier 🤩mbonnin
12/12/2022, 4:59 PM"sometimes"
sounds a bit scary. If you have the option, I'd confirm and document what your backend expects and the cases for sending 401 as HTTP status code vs GraphQL errormbonnin
12/12/2022, 5:00 PMcom.apollographql.apollo3.interceptor.ApolloInterceptor
and catch ApolloHttpException
in there to do everything in a single placembonnin
12/12/2022, 5:01 PMresponse.errors
(in the HTTP 200 case) and the ApolloHttpException.statusCode
(in HTTP 401 case)Stylianos Gakis
12/12/2022, 5:08 PMApolloHttpException
case sounds like smth we can’t due since we use the raw OkHttpClient sometimes too.
As a side not, since this is an option, I guess not going with a okhttp3.Authenticator
is great since then we can avoid having to do a runBlocking
to enter the coroutines world since the apollo interceptor is suspending itself while the okhttp3 one is not.mbonnin
12/12/2022, 5:09 PMwhen we use it through the ApolloClient instance then it comes as a http errorDid you mean "comes as a GraphQL error"?
Stylianos Gakis
12/12/2022, 5:10 PMmbonnin
12/12/2022, 5:10 PMmbonnin
12/12/2022, 5:13 PMmbonnin
12/12/2022, 5:14 PMmbonnin
12/12/2022, 5:16 PMrefreshToken()
method synchronized is not optimal because you might end up with multiple request queued on the lock and all of them refreshing the token. So when your token expires you refresh it 2, 3 or more timesStylianos Gakis
12/12/2022, 5:20 PMmbonnin
12/12/2022, 5:22 PMmbonnin
12/12/2022, 5:23 PMStylianos Gakis
12/12/2022, 5:25 PMmbonnin
12/12/2022, 5:26 PMmbonnin
12/12/2022, 5:26 PMmbonnin
12/12/2022, 5:34 PMRequest
-> Flow<Response>
for cache/`@defer` purposes. If you put your interceptor after configuring the cache and not using @defer
, it should be safe to assume a single responseStylianos Gakis
12/12/2022, 6:00 PM@defer
right now, but who knows if we might in the future, so don’t want to mess this up 😄mbonnin
12/12/2022, 6:00 PMI want the interceptor to be after the cache configuration right?Yes, correct ✅
mbonnin
12/12/2022, 6:01 PM@defer
details but if you end up using it, please reach out, that'll open some interesting questions 🙂Stylianos Gakis
12/12/2022, 6:03 PMwasyl
12/13/2022, 11:49 AMX-APOLLO-OPERATION-NAME
header for every Apollo requestStylianos Gakis
12/20/2022, 1:36 PMrunBlocking
in there to access the datastore, but it seems to work 😄
Thanks for the help and the advice, too bad I couldn’t put it to good use.