https://kotlinlang.org logo
Join SlackCommunities
Powered by
# apollo-kotlin
  • a

    Akash Amin

    12/20/2024, 8:43 PM
    Hey Folks, we are facing an issue with v3 (continuing migration from v2). It's kind of a weird ask bear with me, in v2 when an
    Integer
    overflows it never threw an error, but v3 throws an error e.g
    java.lang.IllegalStateException: 2927716020 cannot be converted to Int
    seemingly related to the exactInt check here. We are under the process of migrating that field to Long by introducing a new scalar type on our graph, but while we migrate to it, is there a workaround that could be used to safely cast to Integer with overflow on v3?
    m
    • 2
    • 13
  • j

    John O'Reilly

    12/21/2024, 5:34 PM
    getting following for sample I'm updating from Apollo 4.0.1 to 4.1.0.....did something change for this?
    Copy code
    :shared:iosArm64Test: Could not find com.apollographql.apollo:apollo-mockserver:4.1.0.
    m
    b
    • 3
    • 7
  • i

    Ife

    12/31/2024, 5:14 PM
    I decided to give @defer another go today considering its Dec. 2024 and its been around for a while. A few issues I've noticed (if someone has come across this and can offer guidance, pls help 🙏) 1. Whilst the console shows
    incremental
    payload being sent, with
    hasNext: true
    each time, the query only sends two response when using
    .toFlow
    -- initial data-fetch (without the deferred items) and empty payload which I believe concludes that call. 2. In the fetch call, we're calling like so for instance:
    Copy code
    apolloClient.query(
                    GetUserQuery(
                        id = userId,
                        skipItem = true,
                        skipOther = false,
                        skipPreference = false,
                        skipDonations = true,
                        skipCards = true,
                        skipFriends = false
                    )
                )
                .toFlow()
                .collect {
                  // handle error via it.hasErrors() 
                  // OR
                  // emit(it.response) // it stops after the first emit
                }
    I thought the @defer should be abit usable now or at least with good error provision but after 5 hours, I'm going to have to drop it and manually fetch queries on a need-to-use bases. Please let me know if there's anything I'm missing! Happy New Year! 🚀
    b
    • 2
    • 12
  • m

    Marcel

    01/17/2025, 11:13 AM
    Hello! Is there any way to unit test the
    isFromCache
    property on a KMP project in
    commonTest
    without building a wrapper? I have tried using
    MockServer
    and
    MockResponse
    , but I see nothing cache-related there. Silly implementation example:
    Copy code
    class DataSource(private val apolloClient: ApolloClient) {
    
        suspend fun getResponse(): CustomObj {
            val response = apolloClient
                .query(RandomQuery())
                .fetchPolicy(FetchPolicy.NetworkFirst)
                .execute()
    
            val isFromCache = response.isFromCache
            
            return CustomObj(
                isCache = isFromCache,
                data = // parsing data
            )
        }
    }
    I want to be able to mock the
    isFromCache
    in the Apollo responses of my unit tests. I have also tried building my own mock Apollo response like this:
    Copy code
    val isFromCache = true        
    val executionContext = mock<ExecutionContext>() {
        every { get(CacheInfo) } returns CacheInfo.Builder()
            .cacheHit(isFromCache)
            .build()
    }
    
    return ApolloResponse.Builder(
        operation = mock<Operation<GetTodayTabQuery.Data>>(),
        requestUuid = uuid4()
    )
    .data(mockData)
    .addExecutionContext(executionContext)
    .build()
    However, I'm not sure you can use
    MockServer
    to return a real
    ApolloResponse
    object (just a
    MockResponse
    ).
    m
    • 2
    • 3
  • s

    Stylianos Gakis

    01/17/2025, 12:48 PM
    Can I safely use the @include directive for an experimental field in our schema which may in the future be removed in a backwards incompatible way? I'm thinking about adding a remotely controlled feature flag, the client uses that flag in the directive to conditionally query or not query for that field. Then if the backend keeps the field we keep the flag on, if the backend removes it in this backwards incompatible way, we flip the flag off and the old clients continue working perfectly fine since the @include is
    false
    so it would never even ask for the field in the first place. Or is it that it still sends it in the request, but the backend knows not to return it if the directive is set to false? So if the backend doesn't even know about the field in the first place then it'd fail the entire thing.
    e
    w
    m
    • 4
    • 8
  • j

    John O'Reilly

    01/18/2025, 12:11 PM
    Not sure this question makes sense but here goes anyway!. I'm wondering about approaches to observing apollo cache etc in case where you have to make separate query for some list of data and then subsequent queries (for each element in list) for related data.....and want access to "flattened" version of data in ViewModel/Presenter etc. Seems like a few possibilities....can do likes of following for example in say a use case (from where we want to expose a flow) 1. query/observe list and then use
    flatMapMerge
    along, for each element in list,
    combine
    using flow returning queries for related data needed 2. query/observe list and just use
    map
    and then make "single shot queries" for data needed for each element Option 1 is more complicated of course but perhaps needed given nature of how we can potentially get multiple updates from queries (maybe from cache first and then network etc). Option 2 might work I guess if we knew data was in cache (or if we were say doing network only request). Anyway, just in case anyone has come across particular patterns for dealing with queries/data like this
    ❤️ 1
    m
    • 2
    • 2
  • e

    Eduard Boloș

    01/27/2025, 11:10 AM
    Hello! Minor nit-pick: the v4.1.1 release notes don't mention the Coroutines bump. I think this might be a breaking change for some (at least, it is for us 😢)
    m
    • 2
    • 20
  • j

    John O'Reilly

    02/06/2025, 6:01 PM
    Congrats @mbonnin!! https://x.com/GraphQL/status/1887527720265130384?t=lTOUSwnTtKV75LqZHmF-Qw&amp;s=19
    💯 5
    🎉 14
    m
    • 2
    • 1
  • e

    Ed Holloway-George

    02/13/2025, 3:47 PM
    I have a bit of a strange use-case, so I don't suppose there's an easy way to do this by the nature of how interceptors work within Apollo. But I am scratching my head to see if it's easy enough to identify the same request from within an
    ApolloInterceptor
    and a
    HttpInterceptor
    to then be able to essentially collate all the information Apollo has for that GraphQL call. An
    ApolloInterceptor
    will supply a UUID for a call, but there's no way to propagate that to an
    HttpInterceptor
    right?
    m
    • 2
    • 9
  • s

    Subodh Nijsure

    02/18/2025, 7:38 PM
    Is there way to retry Apollo Android query if DNS lookup fails? I am running some tasks using Android WorkManager. The work manager is configured to run the task only when network connection is present. Inspiter of that sometimes we see that GQL query fails with DNS lookup failure (perhaps device just connected?) Is there way I can craft the Apollo Error handled that will retry the query with certain delay, if I encounter specific HTTP error and/or name resolution error?
    m
    • 2
    • 2
  • e

    Eduard Boloș

    02/26/2025, 3:08 PM
    Hello! I am confused about something in the documentation, more specifically here:
    By default, the GraphQL spec treats nullable variables as optional, so it's valid to omit them at runtime. In practice, however, this is rarely used and makes the operation's declaration verbose.
    I am not sure that the "so it's valid to omit them at runtime" is actually true. Looking at the linked spec, if hasValue is is not true, and defaultValue doesn't exist, there's no value coercion happening. Which will lead to an error – that's exactly what we are experiencing with our Python server that uses Strawberry. Instead, what we are seeing is that we can omit the nullable variable only if there is a default value defined for it in the schema, which is not clear in Apollo's documentation. Am I making sense? 😄
    m
    s
    • 3
    • 12
  • s

    Sevban Bayir

    03/02/2025, 10:01 PM
    Hi everyone. I have a little bit specific question about apollo's models(data classes) genereated from queries. In a multimodule android project, if we are using REST we'd create DTOs to represent network data and then use mappers to translate these network representations into models we can use in presentation layers. On the other hand when using apollo for android, those DTOs we'd create are already created (generated) by apollo actually. My question is when writing mappers to apollos generated models i feel like im coupling the network layer with data layer more than necessary because in case of graphql is gone than those mappers will be completely useless right ? Im trying to design a scalable codebase and dont want to couple anything more than necessary. Would you suggest creating my own DTOs as network data representations even though apollo creates those models behalf of me, for the sake of loose coupling in mappers ? Your help is much appreciated in advance. Thank you.
    m
    a
    e
    • 4
    • 7
  • a

    agrosner

    03/03/2025, 4:12 PM
    hey, i have a situation where we want to use mock data and construct them with mock values (custom scalars included) what we’ve had to do is do nasty workarounds like this:
    Copy code
    override fun resolveLeaf(context: FakeResolverContext): Any {
            val mergedField = context.mergedField
            val type = mergedField.type.rawType()
            if (type is CustomScalarType) {
                // workaround the fact that Apollo doesn't have an API for constructing adapters
                // so we dont need explicit dependencies constructed here.
                val adapter = __CustomScalarAdapters.responseAdapterFor<Any>(type)
                if (adapter is AdapterResolver<*, *> && type.className == adapter.outputClass.qualifiedName) {
                    @Suppress("UNCHECKED_CAST")
                    return (adapter as AdapterResolver<Any, Any>).convert(resolver.resolve(context, adapter.inputClass))
                }
            }
    
            return super.resolveLeaf(context)
        }
    since the default fake resolver does not handle scalar types. should I file a feature request?
    m
    s
    • 3
    • 11
  • a

    Akash Amin

    03/11/2025, 9:03 PM
    Hi All, I have a problem understanding how using
    @skip
    /
    @include
    directives affect the normalized cache. The scenario is we have 2 operations
    query
    and
    subscription
    that use the same fragment, we want some fields to not be subscribed in the subscription as they never change, to do this we added the
    @skip
    directive on fields of the fragment. The issue is with Apollo v2 the fields that are skipped from a subscription, they are updated as
    null
    on the Apollo store normalized cache and overrides data fetched from the query. Apparently this issue does not happen with Apollo v3. Could you please help understanding what caused this issue/(feature) with Apollo v2 and what was fixed in Apollo v3.
    m
    • 2
    • 5
  • s

    Stylianos Gakis

    03/12/2025, 2:05 PM
    Question regarding Optimistic Updates If the response from the mutation is a failure, due to no internet for example, but we've already written what we'd expect to get back into the cache using optimistUpdates, how should one fix the cache from that point? The UI would at that point show what we'd like the state to be like, but we will after the fact know that the mutation did not go through.
    m
    • 2
    • 16
  • s

    Stylianos Gakis

    03/13/2025, 4:59 PM
    Using the test artifact with
    registerTestResponse
    etc. I have a test where I am testing a ViewModel, some action happens, some state is set to being in a "loading" state, so I want to be able to assert that, and then I want to be able to add the response to the ApolloClient, so that it will return that value back to the suspend function which is waiting for it, so that I can also assert what happens after the network has responded. What happens now instead is that I call the action on my ViweModel, the state is set to be in this pending state, then the suspend function tries to hit the ApolloClient, it does not find the response registered in the test
    TestNetworkTransport
    so it throws with
    No response registered for operation ...
    . Outside of Apollo, I typically make this work using Turbines, where if someone does an
    awaitItem()
    on it, it will not immediately throw, but it will wait a bit to see if someone will add a response to that turbine, and when it's there then it gives it to the caller who was waiting for it in a suspending manner. Does what I say here make sense? I can try to explain it a bit better if not 😊
    m
    • 2
    • 18
  • s

    Stylianos Gakis

    03/20/2025, 2:05 PM
    Just got bit by a mistake in testing which I seem to be repeating quite often and I want to confirm that there is nothing better I can do here besides being more careful. We have two mutations in this shape:
    Copy code
    memberUpdateEmail(input: MemberUpdateEmailInput!): MemberMutationOutput!
    memberUpdateLanguage(input: MemberUpdateLanguageInput!): MemberMutationOutput!
    notice the same response type on both of them. I was writing some tests, and I was enqueuing some responses like this:
    Copy code
    apolloClient.registerSuspendingTestResponse(
     MemberUpdatePhoneNumberMutation(newPhoneNumber),
     MemberUpdatePhoneNumberMutation.Data {
      this.memberUpdatePhoneNumber = this.buildMemberMutationOutput { ... irrelevant what's in here }
     },
    )
    apolloClient.registerSuspendingTestResponse(
     MemberUpdateEmailMutation(newEmail),
     MemberUpdateEmailMutation.Data {
      this.memberUpdatePhoneNumber = this.buildMemberMutationOutput { ... }
     },
    )
    And I could not for the life of me figure out why my tests were failing but it was all here
    Copy code
    MemberUpdateEmailMutation.Data {
     this.memberUpdatePhoneNumber = this.buildMemberMutationOutput { ... }
    },
    Which should have instead been
    Copy code
    MemberUpdateEmailMutation.Data {
     this.memberUpdateEmail = this.buildMemberMutationOutput { ... }
    },
    Notice the difference in which field I am defining in the lambda there? And there was no type-safety related error kicking in here since they both happen to accept the same response type, so it was compiling just fine. Lmk if what I say is clear enough or not 🤗
    m
    • 2
    • 9
  • c

    Colton Idle

    03/28/2025, 5:35 AM
    If we use apollo and have caching enabled. Can we somehow do a full text search of the cached content?
    m
    • 2
    • 2
  • w

    wasyl

    03/31/2025, 10:23 AM
    👋 I'm seeing some
    generateXxxApolloSources
    tasks created during configuration time. It happens when calling
    registerJavaGeneratingTask
    , I think specifically in the
    outputDir.get()
    part — the
    outputDir
    is a provider based on
    outputDir
    argument of
    DefaultDirectoryConnection
    which in turn comes from
    sourcesBaseTaskProvider.flatMap { }
    . So in the end, the directory property is resolved which causes the task to be resolved/created, if I read that right? Or it's a misconfiguration on our end (because e.g. the variants shouldn't be resolved in the first place, or we may be doing something with Apollo tasks) or something else entirely?
    m
    • 2
    • 13
  • s

    Subodh Nijsure

    03/31/2025, 5:29 PM
    Project that I work on we are currently hand crafting Data classes in our unit tests to provide GQL responses. I didn't know about this option generateDataBuilder before I explore using that option is there any plan to "officially" support it. Team doesn't like using "experimental" stuff hence the question;
    m
    • 2
    • 9
  • e

    Eduard Boloș

    04/04/2025, 10:42 AM
    Hello! Quick question about the
    @optional
    directive when used on a non-nullable object. In the generated model, the respective field becomes nullable, but in the
    *Selections
    object, the annotated field's type is still marked with
    .notNull()
    , making it a
    CompiledNotNullType
    . Is that on purpose? Context: we do some shenanigans in our
    CacheResolver
    to avoid some cache misses by returning null instead of nullable fields, and we were trying to do this for a field that is marked not null in the schema generated from the backend, so that we can successfully execute the query even if the user is offline (e.g. with
    NetworkFirst
    ).
    b
    • 2
    • 12
  • j

    John Marshall

    04/07/2025, 3:51 PM
    @bod do we have any target ETA for releasing the incubating cache back into production? You've made a lot of great changes that seem to be getting closer and closer to ready. I also noticed some work around migration which I assumed was part of the hold-up.
    b
    • 2
    • 4
  • m

    Marco Pierucci

    04/08/2025, 10:50 AM
    Hello! Not sure if its the right channel, but not sure also were to ask. I have a dummy polling system with apollo kotlin. Was just playing around today and I noticed the moment my screen turns of/gets blocked Im hit with
    Failed to execute GraphQL http network request
    (Underlying cause is unknown host exception) Is somethign expected from apollo? Or maybe someones knwo this is an android config thingy?
    m
    • 2
    • 6
  • f

    fred

    04/09/2025, 7:59 AM
    👋 hi! we have a significant number of Apollo internal errors happening constantly across all our apps and we're currently trying to understand why they're happening and what we can do about that — full original context is in this thread, but the summary is that writing to cache seems to fail consistently for some of our users and the main culprit seems to be `SQLiteBlobTooBigException`s we're currently planning to experiment with different cursor size to see if that helps, but we would also love to hear from you on a few different points: • can you think of anything else we could look into or investigate? • have you seen any other similar cases like this before where we could try to extract a learning or insight from? • would it be possible for the apolloExceptionHandler to expose more than just the exception thrown so we can maybe learn what are the queries causing the failure, or anything else that might help narrowing things down?
    b
    • 2
    • 8
  • e

    Eduard Boloș

    04/29/2025, 10:34 AM
    Hello! Do you have a recommendation for some static analysis tool that is able to detect if in a GQL query the
    id
    field is not included for objects that have such a field? Or do you think that this is something that could be part of the Apollo tooling? We are using
    id
    as the cache key in our
    CacheKeyGenerator
    implementation, and it would be useful to have such a check so that people's queries don't mess up the cache by mistake (we had several bugs and crashes due to this 😅)
    m
    b
    w
    • 4
    • 14
  • a

    agrosner

    04/29/2025, 12:34 PM
    hey not sure if related, but i did notice something strange. when I have continuous code generation on, there is a new gradle daemon process that keeps spinning up in the IDE. It is using the JBR bundled with the IDE, however our project uses a different java version 17 in the regular Java home location outside of the IDE. this results in at minium two daemons running while IDE is open. To eliminate the plugin as the culprit, where does it get the Java location from?
    m
    b
    • 3
    • 13
  • m

    Marco Pierucci

    04/29/2025, 4:05 PM
    Hello hello! Got a doubt regarding apollo v4 exception handling and authentications 🧵
    m
    • 2
    • 31
  • s

    Seb Jachec

    04/30/2025, 12:42 PM
    Hi! I'm trying to migrate over to the new normalized cache, having followed the docs for Relay-style pagination, but I'm getting a
    NullPointerException
    crash in
    ConnectionMetadataGenerator.metadataForObject
    that I'm having a hard time understanding 🧵
    b
    • 2
    • 22
  • i

    Ife

    05/03/2025, 10:03 AM
    Hi All, I'm hoping i can get some pointers here to help with my issue. We're using
    4..0.0
    and have
    autoPersistedQueries
    enabled. We're also trying to use the
    @defer
    directives for some high-latency fields. Now the issue, whilst we can see in the logs the incremental data, e.g the attached, we are not able to capture this in the query response itself. I've pretty much logged everything I possible can, no errors and no deferred data. Any idea what I should try or where to look?
    b
    • 2
    • 32
  • s

    Seth Madison

    05/07/2025, 3:35 PM
    Would it be possible to add a flag to allow us to treat
    UnusedVariable
    as an error issue instead of just warning? I can file a github issue about this if folks feel it would be useful/make sense.
    m
    w
    • 3
    • 16