All Versions
36
Latest Version
Avg Release Cycle
13 days
Latest Release
-

Changelog History
Page 2

  • v3.2.2 Changes

    2022-04-11

    ๐Ÿš€ A maintenance release to fix the addJvmOverloads option added in 3.2.0 as well as other fixes. If you're using APQs, the mutations are now always send using POST. See #4006 for details and a way to override the behaviour if you really need to.

    Many thanks to @benedict-lim, @olivierg13, @konomae and @sproctor for their contributions ๐Ÿ’™

    ๐Ÿ‘ทโ€ All changes

    • ๐Ÿšš Use a constant for JvmOverloads to avoid a crash due to relocation (#4008)
    • Always use POST for Mutations in APQs (Auto Persisted Queries) (#4011)
    • โž• Add configurable headers to WebSocketNetworkTransport (#3995)
    • ๐Ÿ”€ Handle SqlNormalizedCache merge APIs Exceptions with ApolloExceptionHandler (#4002)
    • โž• Add adapter for java.time.OffsetDateTime (#4007)
    • โœ… โฐ Add tests for date adapters (#3999)
    • ๐Ÿ›  Fix wrong LocalDate and LocalDateTime formats in JavaTimeAdapters (#3997)
  • v3.2.1 Changes

    2022-04-05

    ๐Ÿš€ This release introduces a few improvements and bug fixes.

    โœจ๏ธ [new] ApolloCall<D>.emitCacheMisses(Boolean) (#3980)

    When observing the cache with watch, the behavior was to not emit cache misses at all, which may not desirable in certain cases. With this new option, you can now choose to emit them: in that case responses will be emitted with a null data.

    This can be used like so:

    apolloClient.query(query)
        .fetchPolicy(FetchPolicy.CacheOnly)
        .emitCacheMisses(true)
        .watch()
        .collect { response ->
          // response.data will be null in case of cache misses
        }
    

    This is also closer to the behavior that was in place in v2. Many thanks to @mateuszkwiecinski for the insights and raising the issue!

    ๐Ÿ”ง โš™๏ธ [breaking] Allow configuration of frame types used in SubscriptionWsProtocol and default to Text (#3992)

    0๏ธโƒฃ When using subscriptions over WebSockets with SubscriptionWsProtocol (the default), the frames were sent in the binary format. It was reported that this was not compatible with certain servers (DGS , graphql-java-kickstart) that are expecting text 0๏ธโƒฃ frames. This is now fixed and the default is to send text frames.

    โš ๏ธ This may be a breaking change if your server expects binary frames only!

    ๐Ÿ”ง If that is the case, you can use the new frameType option to configure the frame type to be sent:

    client = ApolloClient.Builder()
        .webSocketServerUrl("wss://...")
        .wsProtocol(GraphQLWsProtocol.Factory(frameType = WsFrameType.Binary))
        .build()
    

    Many thanks to @Krillsson and @aviewfromspace1 for the insights and raising the issue!

    ๐Ÿ‘ทโ€ All changes

    • ๐Ÿ‘ Allow configuration of frame types used in SubscriptionWsProtocol and default to Text (#3992)
    • โž• add ApolloRequest.newBuilder(operation: Operation<E>) (#3988)
    • โž• Add exception handlers to ApolloCacheInterceptor and SqlNormalizedCache (#3989)
    • ๐Ÿ—„ ๐Ÿ“  Fix some @DeprecatedSince annotations (#3983)
    • ๐Ÿ‘“ add ApolloCall.emitCacheMisses(Boolean) (#3980)
    • โš™๏ธ Fix fragments on the root query type in operationBased codegen (#3973)

    โค๏ธ External contributors

    Many thanks to @AdamMTGreenberg and @Krillsson for the contributions! ๐Ÿ™

  • v3.2.0 Changes

    2022-03-29

    ๐Ÿš€ ๐Ÿ’™ Thanks to @undermark5, @demoritas, @rkoron007, @akshay253101, @StylianosGakis, @Goooler, @jeffreydecker, @theBradfo, @anderssandven and @olivierg13 for contributing to this release.

    ๐Ÿ›  This version adds JS WebSocket support, more options to deal with __typename amongst other features and bugfixes.

    ๐Ÿ‘ โœจ๏ธ [new] JS WebSocket support (#3913)

    ๐Ÿ”– Version 3.2.0 now has WebSocket support for Javascript targets courtesy of @undermark5! This is a huge milestone and means the JS target is now even closer to its JVM and iOS counterparts.

    ๐Ÿง | | jvm | Apple | js | linuxX64 | --- | :---: |:-----:|:----:| :---: | | apollo-api (models)|โœ…| โœ… | โœ… |โœ…| | apollo-runtime (network, query batching, apq, ...) |โœ…| โœ… | โœ… |๐Ÿšซ| | apollo-normalized-cache |โœ…| โœ… | โœ… |๐Ÿšซ| | apollo-adapters |โœ…| โœ… | โœ… |๐Ÿšซ| | apollo-normalized-cache-sqlite |โœ…| โœ… | ๐Ÿšซ |๐Ÿšซ| | apollo-http-cache |โœ…| ๐Ÿšซ | ๐Ÿšซ |๐Ÿšซ|

    ๐Ÿ’ป The implementation is based on the ws library on Node and the WebSocket API on the browser and inspired by Ktor.

    โœจ๏ธ [new] Fine grained __typename control (#3939)

    This version generates non-nullable fragments when it knows the fragment is always present:

    {
      cat {
        # Because Animal is a supertype of Cat this condition will always be true
        ... on Animal {
          species
        }
      }
    }
    

    ๐Ÿ‘ In addition, it introduces a addTypename Gradle option to have better control over when to add the __typename field:

    /**
     * When to add __typename. One of "always", "ifFragments", "ifAbstract" or "ifPolymorphic"
     *
     * - "always": Add '__typename' for every compound field
     *
     * - "ifFragments": Add '__typename' for every selection set that contains fragments (inline or named)
     * This is adding a lot more '__typename' than the other solutions and will be certainly removed in
     * a future version. If you require '__typename' explicitly, you can add it to your queries.
     * This causes cache misses when introducing fragments where no fragment was present before and will be certainly removed in
     * a future version.
     *
     * - "ifAbstract": Add '__typename' for abstract fields, i.e. fields that are of union or interface type
     * Note: It also adds '__typename' on fragment definitions that satisfy the same property because fragments
     * could be read from the cache and we don't have a containing field in that case.
     *
     * - "ifPolymorphic": Add '__typename' for polymorphic fields, i.e. fields that contains a subfragment
     * (inline or named) whose type condition isn't a super type of the field type.
     * If a field is monomorphic, no '__typename' will be added.
     * This adds the bare minimum amount of __typename but the logic is substantially more complex and
     * it could cause cache misses when using fragments on monomorphic fields because __typename can be
     * required in some cases.
     *
     * Note: It also adds '__typename' on fragment definitions that satisfy the same property because fragments
     * could be read from the cache and we don't have a containing field in that case.
     *
     * Default value: "ifFragments"
     */
    

    ๐Ÿ“„ You can read more in the corresponding Typename.md design document.

    ๐Ÿ“‡ โœจ๏ธ [new] Maven publishing for multi-module apollo metadata (#3904)

    ๐Ÿ“‡ The Apollo Gradle plugin now creates a new "apollo" publication if maven-publish is found. This means you can now publish the Apollo metadata to a maven repository:

  • v3.1.0 Changes

    2022-02-07

    ๐Ÿ”– Version 3.1.0 introduces new APIs for testing, mapping scalars as well a redesigned cache pipeline. ๐Ÿ›  It also contains bugfixes around the @include directives, MemoryCache and GraphQL validation amongst other changes.

    ๐Ÿ“ฆ โš™๏ธ [breaking] Fragment package name and useSchemaPackageNameForFragments (#3775)

    ๐Ÿ“ฆ If you're using packageNamesFromFilePaths(), the package name of generated fragment classes has changed.

    ๐Ÿ“ฆ Different generated types have different package names:

    • Generated types coming from operations are generated based on the operation path
    • Generated types coming from the schema (input objects, custom scalars and enums) are generated based on the schema path

    Previously, fragments were using the schema path which is inconsistent because fragments are not defined in the schema but are executable files, like operations.

    ๐Ÿ”– Version 3.1.0 now uses the same logic for fragments as for operations. To revert to the previous behaviour, you can ๐Ÿ“ฆ use useSchemaPackageNameForFragments:

    apollo {
      useSchemaPackageNameForFragments.set(true)
    }
    

    This is also done automatically if you're using useVersion2Compat(). Moving forward, the plan is to โœ‚ remove useSchemaPackageNameForFragments in favor of setting a custom PackageNameGenerator. If you have use cases ๐Ÿ“ฆ that require useSchemaPackageNameForFragments, please reach out .

    โœ… โœจ [New] QueueTestNetworkTransport (#3757)

    โœ… 3.1.0 introduces QueueTestNetworkTransport to test at the GraphQL layer without needing to run an HTTP server.

    ๐Ÿ”ง To use it, configure your ApolloClient:

    // This uses a QueueTestNetworkTransport that will play the queued responses
    val apolloClient = ApolloClient.Builder()
        .networkTransport(QueueTestNetworkTransport())
        .build()
    

    โœ… You can then use the enqueueTestResponse extension function to specify the GraphQL responses to return:

    val testQuery = GetHeroQuery("001")
    val testData = GetHeroQuery.Data {
      hero = droidHero {
        name = "R2D2"
      }
    }
    apolloClient.enqueueTestResponse(testQuery, testData)
    val actual = apolloClient.query(testQuery).execute().data!!
    assertEquals(testData.hero.name, actual.hero.name)
    

    ๐Ÿคก โœจ [New] MockServerHandler (#3757)

    โœ… If you're testing at the HTTP layer, you can now define your own MockServerHandler to customize how the server is going to answer to requests:

    val customHandler = object : MockServerHandler {
      override fun handle(request: MockRequest): MockResponse {
        return if (/* Your custom logic here */) {
          MockResponse(
              body = """{"data": {"random": 42}}""",
              headers = mapOf("X-Test" to "true"),
          )
        } else {
          MockResponse(
              body = "Internal server error",
              statusCode = 500,
          )
        }
      }
    }
    val mockServer = MockServer(customHandler)
    

    โœจ [New] FetchPolicy.CacheAndNetwork (#3828)

    Previously, FetchPolicys were limited to policies that emitted at most one response. There was a executeCacheAndNetwork() method but it felt asymmetrical. This version introduces FetchPolicy.CacheAndNetwork that can emit up to two responses:

    apolloClient.query(query)
        // Check the cache and also use the network (1 or 2 values can be emitted)
        .fetchPolicy(FetchPolicy.CacheAndNetwork)
        // Execute the query and collect the responses
        .toFlow().collect { response ->
          // ...
        }
    

    โœจ [New] ApolloCall<D>.fetchPolicyInterceptor(interceptor: ApolloInterceptor) (#3743)

    If you need more customized ways to fetch data from the cache or more fine-grained error handling that does not come with the built-in FetchPolicy, you can now use fetchPolicyInterceptor:

    // An, interceptor that will only use the network after getting a successful response
    val refetchPolicyInterceptor = object : ApolloInterceptor {
      var hasSeenValidResponse: Boolean = false
      override fun <D : Operation.Data> intercept(
          request: ApolloRequest<D>,
          chain: ApolloInterceptorChain
      ): Flow<ApolloResponse<D>> {
        return if (!hasSeenValidResponse) {
          CacheOnlyInterceptor.intercept(request, chain).onEach {
            if (it.data != null) {
              // We have valid data, we can now use the network
              hasSeenValidResponse = true
            }
          }
        } else {
          // If for some reason we have a cache miss, get fresh data from the network
          CacheFirstInterceptor.intercept(request, chain)
        }
      }
    }
    
    apolloClient.query(myQuery)
        .refetchPolicyInterceptor(cacheOnlyInterceptor)
        .watch()
        .collect {
          //
        }
    

    โœจ [New] Service.mapScalar Gradle API (#3779)

    You can now use mapScalar to specify your scalar mappings:

    apollo {
      // Replace 
      customScalarsMapping.set(mapOf(
          "Date" to "java.util.Date"
      ))
    
      // With
      mapScalar("Date", "java.util.Date")
    }
    

    mapScalar also works with built-in scalar types so you can map the ID type to a kotlin Long:

    apollo {
      // This requires registering an adapter at runtime with `addCustomScalarAdapter()` 
      mapScalar("ID", "kotlin.Long")
    }
    

    As an optimization, you can also provide the adapter at compile time. This will avoid a lookup at runtime everytime such a scalar is read:

    apollo {
      // No need to call `addCustomScalarAdapter()`, the generated code will use the provided adapter 
      mapScalar("ID", "kotlin.Long", "com.apollographql.apollo3.api.LongAdapter")
    }
    

    For convenience, a helper function is provided for common types:

    apollo {
      // The generated code will use `kotlin.Long` and the builtin LongAdapter 
      mapScalarToKotlinLong("ID")
    
      // The generated code will use `kotlin.String` and the builtin StringAdapter
      mapScalarToKotlinString("Date")
    
      // The generated code will use `com.apollographql.apollo3.api.Upload` and the builtin UploadAdapter
      mapScalarToUpload("Upload")
    }
    

    ๐Ÿšง [Changed] convertApolloSchema and downloadApolloSchema now use paths relative to the root of the project (#3773, #3752)

    Apollo Kotlin adds two tasks to help to manage schemas: convertApolloSchema and downloadApolloSchema. These tasks are meant to be used from the commandline.

    Previously, paths were interpreted using the current working directory with File(path). Unfortunately, this is unreliable because Gradle might change the current working directory in some conditions ( ๐Ÿ‘€ see Gradle#13927 or Gradle#6074 for an example).

    With 3.1.0 and onwards, paths, will be interpreted relative to the root project directory (project.rootProject.file(path)):

  • v3.0.0 Changes

    2021-12-15

    ๐Ÿš€ This is the first stable release for ~Apollo Android 3~ Apollo Kotlin 3 ๐ŸŽ‰!

    ๐Ÿ“š There is documentation, โšก๏ธ a migration guide and a blog post coming soon (we'll update these notes when it's out).

    In a nutshell, Apollo Kotlin 3 brings:

    • ๐Ÿ“„ coroutine APIs for easier concurrency
    • ๐Ÿ“„ multiplatform support makes it possible to run the same code on Android, JS, iOS, MacOS and linux
    • ๐Ÿ“„ responseBased codegen is a new optional codegen that models fragments as interfaces
    • SQLite batching makes reading from the SQLite cache significantly faster
    • ๐Ÿ— Test builders offer a simple APIs to build fake models for your tests
    • ๐Ÿ“„ The @typePolicy and @fieldPolicy directives make it easier to define your cache ids at compile time
    • ๐Ÿ“œ The @nonnull directive catches null values at parsing time, so you don't have to deal with them in your UI code

    ๐Ÿ†“ Feel free to ask questions by either opening an issue on our GitHub repo , joining the community or stopping by our channel in the KotlinLang Slack(get your invite here).

  • v3.0.0-rc03 Changes

    2021-12-13

    ๐Ÿ›  Compared to the previous RC, this version adds a few new convenience API and fixes 3 annoying issues.

    ๐Ÿ’™ Many thanks to @ mateuszkwiecinski, @ schoeda and @ fn-jt for all the feedback ๐Ÿ’™

    โœจ New APIs

    • ๐Ÿ‘‰ Make ApolloCall.operation public (#3698)
    • โž• Add SubscriptionWsProtocolAdapter (#3697)
    • โž• Add Operation.composeJsonRequest (#3697)

    ๐Ÿ›  ๐Ÿชฒ Bug fixes

    • ๐Ÿ‘ Allow repeated @fieldPolicy (#3686)
    • ๐Ÿ›  Fix incorrect merging of nested objects in JSON (#3672)
    • ๐Ÿ›  Fix duplicate query detection (#3699)
  • v3.0.0-rc02 Changes

    2021-12-10

    ๐Ÿ’™ Many thanks to @michgauz, @joeldenke, @rohandhruva, @schoeda, @CoreFloDev and @sproctor for all the feedback ๐Ÿ’™

    ๐Ÿ”€ โš™๏ธ [breaking] Merge ApolloQueryCall, ApolloSubscriptionCall, ApolloMutationCall (#3676)

    In order to simplify the API and keep the symmetry with ApolloRequest<D> and ApolloResponse<D>, ApolloQueryCall<D, E>, ApolloSubscriptionCall<D, E>, ApolloMutationCall<D, E> are replaced with ApolloCall<D>. This change should be mostly transparent but it's technically a breaking change. If you are passing ApolloQueryCall<D, E> variables, it is safe to drop the second type parameter and use ApolloCall<D> instead.

    โœจ [New] Add WebSocketNetworkTransport.reconnectWhen {} (#3674)

    You now have the option to reconnect a WebSocket automatically when an error happens and re-subscribe automatically after the reconnection has happened. To do so, use the webSocketReconnectWhen parameter:

    val apolloClient = ApolloClient.Builder()
        .httpServerUrl("http://localhost:8080/graphql")
        .webSocketServerUrl("http://localhost:8080/subscriptions")
        .wsProtocol(
            SubscriptionWsProtocol.Factory(
                connectionPayload = {
                  mapOf("token" to upToDateToken)
                }
            )
        )
        .webSocketReconnectWhen {
          // this is called when an error happens on the WebSocket
          it is ApolloWebSocketClosedException && it.code == 1001
        }
        .build()
    

    ๐Ÿ‘ Better Http Batching API (#3670)

    ๐Ÿ”ง The HttpBatchingEngine has been moved to an HttpInterceptor. You can now configure Http batching with a specific method:

    apolloClient = ApolloClient.Builder()
        .serverUrl(mockServer.url())
        .httpBatching(batchIntervalMillis = 10)
        .build()
    

    All changes:

    • โž• Add 2.x symbols (Rx2Apollo, prefetch(), customAttributes(), ApolloIdlingResource.create()) to help the transition (#3679)
    • โž• Add canBeBatched var to ExecutionOptions (#3677)
    • ๐Ÿ”€ Merge ApolloQueryCall, ApolloSubscriptionCall, ApolloMutationCall (#3676)
    • โž• Add WebSocketNetworkTransport.reconnectWhen {} (#3674)
    • ๐Ÿšš Move BatchingHttpEngine to a HttpInterceptor (#3670)
    • โž• Add exposeErrorBody (#3661)
    • ๐Ÿ›  fix the name of the downloadServiceApolloSchemaFromRegistry task (#3669)
    • ๐Ÿ›  Fix DiskLruHttpCache concurrency (#3667)
  • v3.0.0-rc01 Changes

    2021-12-07

    ๐Ÿš€ This version is the release candidate for Apollo Android 3 ๐Ÿš€. Please try it and report any issues, we'll fix them urgently.

    ๐Ÿ“š There is documentation and ๐Ÿ“„ a migration guide. More details are coming soon. In a nutshell, Apollo Android 3 brings, amongst other things:

    • ๐Ÿ“„ coroutine APIs for easier concurrency
    • ๐Ÿ“„ multiplatform support makes it possible to run the same code on Android, JS, iOS, MacOS and linux
    • ๐Ÿ“„ responseBased codegen is a new optional codegen that models fragments as interfaces
    • SQLite batching makes reading from the SQLite cache significantly faster
    • ๐Ÿ— Test builders offer a simple APIs to build fake models for your tests
    • ๐Ÿ“„ The @typePolicy and @fieldPolicy directives make it easier to define your cache ids at compile time
    • ๐Ÿ“œ The @nonnull directive catches null values at parsing time, so you don't have to deal with them in your UI code

    0๏ธโƒฃ Compared to beta05, this version changes the default value of generateOptionalOperationVariables, is compatible with ๐Ÿ”ง Gradle configuration cache and fixes a few other issues.

    โš™๏ธ API changes

    Optional operation variables (#3648) (breaking)

    0๏ธโƒฃ The default value for the generateOptionalOperationVariables config is now true.

    What this means:

    • 0๏ธโƒฃ By default, operations with nullable variables will be generated with Optional parameters
    • You will need to wrap your parameters at the call site

    For instance:

    query GetTodos($first: Int, $offset: Int) {
      todos(first: $first, offset: $offset) {
        ...Todo
      }
    }
    
    // Before
    val query = GetTodosQuery(100, null)
    
    // After
    val query = GetTodosQuery(Optional.Present(100), Optional.Absent)
    
    
    • If you prefer, you can set generateOptionalOperationVariables to false to generate non-optional parameters globally
    • This can also be controlled on individual variables with the @optional directive
    • More information about this can be found here

    We think this change will make more sense to the majority of users (and is consistent with Apollo Android v2's behavior) even though it may be more verbose, which is why it is possible to change the behavior via the generateOptionalOperationVariables config.

    ๐Ÿ”ง To keep the beta05 behavior, set generateOptionalOperationVariables to false in your Gradle configuration:

    apollo {
      generateOptionalOperationVariables.set(false)
    }
    

    ๐Ÿ— ApolloClient.Builder improvements (#3647)

    ๐Ÿ— You can now pass WebSocket related options to the ApolloClient.Builder directly (previously this would have been done via NetworkTransport):

    // Before
    val apolloClient = ApolloClient.Builder()
        // (...)
        .subscriptionNetworkTransport(WebSocketNetworkTransport(
            serverUrl = "https://example.com/graphql",
            idleTimeoutMillis = 1000L,
            wsProtocol = SubscriptionWsProtocol.Factory()
        ))
        .build()
    
    // After
    val apolloClient = ApolloClient.Builder()
        // (...)
        .wsProtocol(SubscriptionWsProtocol.Factory())
        .webSocketIdleTimeoutMillis(1000L)
        .build()
    

    โฌ†๏ธ Upgrade to OkHttp 4 (#3653) (breaking)

    โฌ†๏ธ This version upgrades OkHttp to 4.9.3 (from 3.12.11). This means Apollo Android now requires Android apiLevel 21 ๐Ÿ‘ +. As OkHttp 3 enters end of life at the end of the year and the vast majority of devices now support apiLevel 21, โฌ†๏ธ we felt this was a reasonable upgrade.

    ๐Ÿ›  ๐Ÿชฒ Bug fixes

    • ๐Ÿ›  Fixed an issue where it was not possible to restart a websocket after a network error (#3646)
    • ๐Ÿ›  Fixed an issue where Android Java projects could not use the Apollo Gradle plugin (#3652)

    ๐Ÿ‘ท All Changes

    • โšก๏ธ Update a few dependencies (#3653)
    • ๐Ÿ›  Fix Android Java projects (#3652)
    • ๐Ÿ”ฆ Expose more configuration options on ApolloClient.Builder (#3647)
    • ๐Ÿ›  Fix restarting a websocket after a network error (#3646)
    • ๐Ÿ”„ Change optional default value (#3648)
    • ๐Ÿ›  Fix configuration cache (#3645)
  • v2.5.14 Changes

    2022-11-18

    ๐Ÿš€ A patch release to fix an issue where the ApolloCall could end up in a bad state. Many thanks to @WilliamsDHI for diving into this ๐Ÿ’™!

    ๐Ÿ‘ทโ€ All changes

    • โšก๏ธ update terminate and responseCallback methods to return Optional.absent() in IDLE/TERMINATED state (#4383)
  • v2.4.6 Changes

    November 30, 2020

    ๐Ÿ”– Version 2.4.6 is a minor release with fixes around multiplatform, normalized cache and others. Many thanks to @tylerbwong and @lwasyl for their work on the metalava integration and enum serialization respectively.

    Full Changelog

    [Normalized cache] Add interface for classes generated for enum types and fix sealed classes json representation (#2776)
    ๐Ÿ”ง [Multiplatform] fix NSURLSession configuration (#2777)
    โœ… [Test] adding test coverage (#2770)
    โช [Runtime] revert to okhttp 3 to support older versions of Android (#2769)
    ๐Ÿ”Œ [Gradle Plugin] make convertApolloSchema never up-to-date (#2761)
    [Multiplatform] Do not use Java8 Duration (#2767)
    ๐Ÿ— [Build scripts] Fix error.NonExistentClass in Metalava Signature Files (#2755)
    ๐Ÿ“ฆ [codegen] Honor packageName for schema types as well (#2759)