Marco Pierucci
11/24/2022, 2:48 PMcreateAllAndroidVariantServices
so each variants will have their corresponding generated code, which is good.
It seems though than when mapping to a domain layer I'd have to replicate mappers for the shared components ( one mapper that target each variant source code) which its a bit tedious. Has someone faced a similar scenario and could share maybe a better solution/ approach ?Jan Skrasek
12/08/2022, 9:25 AMStylianos 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 🤩Marco Pierucci
12/14/2022, 2:46 PMCould not set unknown property 'nameSuffix' for extension 'apollo'
🤔Spencer
01/09/2023, 8:19 PMAccount:12345.users()
Account:12345.users({search: "Bob"})
Account:12345.users({search: "Bob Smith"})
The problem is that we want to update the cache for all the lists after the mutation succeeded. I have thought about updating the cache manually with writeOperation
but we would run into not knowing every single search query text, or having to keep a list of every time a query was made with the search text. The same would apply trying to use refetch queries in the mutation collect, or even just deleting the cache key from the store with apollo.apolloStore.remove(CacheKey(key))
.bod
01/17/2023, 9:56 AMrocketraman
01/19/2023, 7:51 PM"kotlin.List<kotlin.String>"
I get an invalid character on <
. Is there a way to have my custom type mapping be a list? If not, I'll create a wrapper type.dorche
01/20/2023, 10:50 PMHttpResponse.body
returns BufferedSource and I am not sure how to read it without closing the stream.
The json parsing itself is pretty simple so I am fine with manually parsing but I get an exception with my current codeagrosner
01/24/2023, 4:53 PMParijat Shah
01/26/2023, 7:17 AMclose()
and create new ApolloClient with the same OkHttpClient instance. But this is not working. None of the query
or mutation
operation result in any http request. ( Confirmed using charles) Everything works as expected if I don't call .close()
. I need to call .close()
to terminate subscriptions for the older
profile and then create new subscriptions.
Does anyone know what's happening under the hood when ApolloClient. close()
is called?dorche
01/26/2023, 12:33 PMtype Query {
games: [Games!]!
}
This results in a Response adapter with the following fromJson code
public override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): GetGamesQuery.Data {
var _games: List<GetGamesQuery.AllAccount>? = null
while(true) {
when (reader.selectName(RESPONSE_NAMES)) {
0 -> _games = Games.obj().list().fromJson(reader, customScalarAdapters)
else -> break
}
}
return GetGamesQuery.Data(
games = _games!!
)
}
But when my server encounters a “GraphQL” when running this query, the response that it sends down fails to parse, details in 🧵Ron Aharoni
01/29/2023, 6:47 AMStylianos Gakis
01/31/2023, 3:28 PMexecute
on an operation, since that’s what it does internally anyway. So at any query we could theoretically replace it with toFlow
and assume all responses can return more results instead of just one (I think with deferred responses that’s was the idea)
Now I have a screen in Android, where I was checking out removing all configuration changes, so I applied all of these and let compose handle all config changes (testing language changes here in my case).
Thing is, for that screen I am testing, I realize we have one part of the screen which shows some string that comes from the backend as-is, meaning it takes what locale header we send it, and responds accordingly, while the other strings of the text are local, so they update immediately when we do a language change, which does not restart the activity, since the Apollo query isn’t re-fetched obviously. If I let the activity re-create itself I get that for free since the entire thing restarts from the beginning.
So finally what I am wondering about. Is there any way I can somehow hook something into the apollo-client, so that if there is ever a locale change, I can ask it to re-fetch every flow it’s got open at the moment, where it will then fetch the correct locale since the interceptor will then get the correctly changed locale and append it in the HTTP headers? Does this idea even make sense conceptually? 😄John O'Reilly
02/04/2023, 3:34 PMColton Idle
02/07/2023, 12:35 AMColton Idle
02/07/2023, 7:51 PMColton Idle
02/08/2023, 4:29 PMSean Proctor
02/09/2023, 11:40 AMColton Idle
02/09/2023, 3:12 PMColton Idle
02/10/2023, 3:09 PM//pseudocode
returnresponse = apolloClient.query(GetBooksQUery(10)).execute()
so GetBooksService is pretttttty thin, but is there anything stateful about it? This is important for me to know because I currently have the service marked as a @Singleton
but i know marking something as a singleton thats not stateful is wastefulagrosner
02/14/2023, 7:15 PM> No matching variant of project :domain was found. The consumer was configured to find a usage of 'apollo-used-coordinates' of a component, as well as attribute 'com.apollographql.service' with value 'api' but
but we only use the service from api2
in that module.Spencer
02/16/2023, 9:08 PMCacheAndNetwork
from emitting 2 values when the cache value and network value are the same?Parijat Shah
02/22/2023, 10:44 PMParijat Shah
02/24/2023, 8:32 PMsubscription(someSubscription).toFlow().retryWhen { t, attempt ->
delay(attempt * attempt * 10000)
true
}
java.io.EOFException: null
at okio.RealBufferedSource.require(RealBufferedSource.kt:199)
at okio.RealBufferedSource.readByte(RealBufferedSource.kt:209)
at okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119)
at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102)
at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293)
at okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
com.apollographql.apollo3.exception.ApolloNetworkException: Network error while executing onDisplayTimeUpdated
at com.apollographql.apollo3.network.ws.WebSocketNetworkTransport$execute$$inlined$map$1$2.emit(Emitters.kt:246)
at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
at kotlinx.coroutines.flow.internal.SafeCollectorKt$emitFun$1.invoke(SafeCollector.kt:15)
at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:87)
at kotlinx.coroutines.flow.internal.SafeCollector.emit(SafeCollector.kt:66)
at com.apollographql.apollo3.network.ws.WebSocketNetworkTransport$execute$3.invokeSuspend(WebSocketNetworkTransport.kt:271)
at com.apollographql.apollo3.network.ws.WebSocketNetworkTransport$execute$3.invoke
at com.apollographql.apollo3.network.ws.WebSocketNetworkTransport$execute$3.invoke
at com.apollographql.apollo3.internal.FlowsKt$transformWhile$1$invokeSuspend$$inlined$collectWhile$1.emit(flows.kt:53)
at com.apollographql.apollo3.internal.FlowsKt$transformWhile$1$invokeSuspend$$inlined$collectWhile$2.emit(flows.kt:38)
at com.apollographql.apollo3.network.ws.WebSocketNetworkTransport$execute$$inlined$filter$1$2.emit(Emitters.kt:223)
at kotlinx.coroutines.flow.SubscribedFlowCollector.emit
at kotlinx.coroutines.flow.SharedFlowImpl.collect$suspendImpl(SharedFlow.kt:383)
at kotlinx.coroutines.flow.SharedFlowImpl$collect$1.invokeSuspend
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Colton Idle
02/25/2023, 6:09 PMagrosner
02/25/2023, 7:18 PMagrosner
02/27/2023, 7:22 PMDon't know how to instantiate leaf URL
We have a set of scalar adapters which are correctly fed into the databuilders. in the fakeResolver
the order of operations is such:
val leafValue = resolver.resolveLeaf(FakeResolverContext(path, id, mergedField))
if (type is CustomScalarType) {
the resolver
itself seems to run without any knowledge of scalars in the `DefaultFakeResolver`:
else -> {
val type = enumTypes.find { it.name == name } ?: error("Don't know how to instantiate leaf $name")
is this expected? I could not find anything in the docs for data buildersPhil Saul
02/28/2023, 1:38 PMgenerateApolloSources
task will generate some data classes that are exactly the same, is there a way to configure the plugin so that only one of each of these classes is generated and they are re-used in the respective queries?Cody Roueche
03/02/2023, 4:11 PMCacheAndNetwork
fetch policy to know if the data coming through the flow is from cache or if it's from the network?Seth Madison
03/02/2023, 7:53 PMCall
takes order 45ms on a modern MBP in Chrome, and parsing parsing the response takes order 70ms.
This compared with ~5ms to build the same Call
and ~2ms to parse it using the JS Apollo client.
Are there tricks that folks know of to improve the situation?
We’re considering just using external
functions that are implemented on the JS side to make the GraphQL queries.Seth Madison
03/02/2023, 7:53 PMCall
takes order 45ms on a modern MBP in Chrome, and parsing parsing the response takes order 70ms.
This compared with ~5ms to build the same Call
and ~2ms to parse it using the JS Apollo client.
Are there tricks that folks know of to improve the situation?
We’re considering just using external
functions that are implemented on the JS side to make the GraphQL queries.mbonnin
03/02/2023, 9:14 PMCall
part especially looks loooong. There's nothing crazy going on there. Feel free to open an issue and we'll investigate thisSeth Madison
03/02/2023, 11:33 PMCall
building (and request making) process.