### GraphQL Operation Execution Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer draft API.md Illustrates a GraphQL operation execution response, including errors and data. This example shows the structure of a response that might be returned during operation execution. ```graphql message = Cannot resolve isColor, locations = [Location(line = 12, column = 11)], path=[computers, 1, screen, isColor], extensions = null, nonStandardFields = null ) ], data=Data( computers=[ Computer( id=Computer1, computerFields=ComputerFields( cpu=386, year=1993, screen=Screen( resolution=640x480, screenFields=null ) ) ), Computer( id=Computer2, computerFields=ComputerFields( cpu=486, year=1996, screen=Screen( resolution=800x600, screenFields=null ) ) ) ] ) ) ``` -------------------------------- ### JSON Response for Users Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/home.mdx Example JSON response for a user list query. ```json { "data": { "allUsers": [ { "id": 1, "name": "John Smith" }, { "id": 2, "name": "Jane Doe" } ] } } ``` -------------------------------- ### GraphQL Operation Query Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/file-types.mdx Example of a GraphQL operation file using the '.graphql' extension. These files contain executable definitions like queries, mutations, and subscriptions, which Apollo Kotlin compiles into type-safe models. ```graphql query MyQuery { field1 field2 ... } ``` -------------------------------- ### Type Set Resolution Example 2 with Turtle Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Glossary.md Extends the type set resolution example to include a 'Turtle' type, illustrating how abstract type sets can generate both interfaces and implementations for specific types. ```graphql type Lion implements Animal & WarmBlooded type Cat implements Animal & WarmBlooded & Pet type Turtle implements Animal & Pet type Panther implements Animal & WarmBlooded - [Animal, Pet, WarmBlooded] => Cat (concrete) - [Animal, WarmBlooded] => [Lion, Panther] (concrete) // To access `species` in a polymotphic way and account for new types being added - [Animal] => (abstract) // Will be generated as both an implementation (for the Turtle possible type) and also as an interface to access common Pet fields with Cat - [Animal, Pet] => [Turtle] (concrete) ``` -------------------------------- ### GraphQL Query for Users Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/home.mdx Example GraphQL query to fetch a list of users. ```graphql query Users { allUsers(groupId: 2) { id name } } ``` -------------------------------- ### Normalized Cache Records Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Normalized cache overview.md Illustrates the flat key-record structure after normalization, showing how shared data like missions are stored only once. ```plaintext Cache key `QUERY_ROOT` `launches({"after":null,"pageSize":2})` `Launch:109` `Mission:Starlink-15` `Launch:108` ``` ```plaintext Record `{launches({"after":null,"pageSize":2})=CacheKey(launches({"after":null,"pageSize":2}))}` `{cursor=1605979020, hasMore=true, launches=[CacheKey(Launch:109), CacheKey(Launch:108)]}` `{__typename=Launch, id=109, site=CCAFS SLC 40, mission=CacheKey(Mission:Starlink-15)}` `{name=Starlink-15, missionPatch({"size":"SMALL"})=https://images2.imgbox.com/9a/96/nLppz9HW_o.png, __typename=Mission}` `{__typename=Launch, id=108, site=VAFB SLC 4E, mission=CacheKey(Mission:Starlink-15)}` ``` -------------------------------- ### GraphQL Schema Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer draft API.md Defines the types used in the GraphQL schema, including Computer, Screen, and their fields. ```graphql type Query { computers: [Computer!]! } type Computer { id: ID! cpu: String! year: Int! screen: Screen! } type Screen { resolution: String! isColor: Boolean! } ``` -------------------------------- ### Type Set Resolution Example 1 Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Glossary.md Shows how type sets are resolved to concrete or abstract types based on the implemented interfaces. This example demonstrates resolution for a simple set of types. ```graphql type Lion implements Animal & WarmBlooded type Cat implements Animal & WarmBlooded & Pet - [Animal, Pet, WarmBlooded] => Cat (concrete) - [Animal, WarmBlooded] => Lion (concrete) // To access `species` in a polymotphic way and account for new types being added - [Animal] => (abstract) ``` -------------------------------- ### Example Persisted Query Manifest JSON Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/persisted-queries.mdx An example of the JSON structure for an operation manifest, which acts as a safelist of trusted operations. ```json { "format": "apollo-persisted-query-manifest", "version": 1, "operations": [ { "id": "e0321f6b438bb42c022f633d38c19549dea9a2d55c908f64c5c6cb8403442fef", "body": "query GetItem { thing { __typename } }", "name": "GetItem", "type": "query" } ] } ``` -------------------------------- ### Implement executeApolloOperation for Non-JS Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/js-interop.mdx Provide a non-JS implementation for `executeApolloOperation` using your preferred HTTP client and `parseJsonResponse`. This example uses `yourHttpClient` and `BufferedSourceJsonReader`. ```kotlin // non-js implementation actual suspend fun JsonHttpClient.executeApolloOperation( operation: Operation, ): D? { val body = buildJsonString { operation.composeJsonRequest(this) } val bytes = yourHttpClient.execute(somePath, body) val response = operation.parseJsonResponse(BufferedSourceJsonReader(Buffer().write(bytes))) return response.data } ``` -------------------------------- ### Example Received Payloads for @defer Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer merging implementation.md Illustrates the sequence of JSON payloads received when using the @defer directive, showing initial data and subsequent fragments. ```json // Payload 1 {"data":{"computers":[{"id":"Computer1"},{"id":"Computer2"}]},"hasNext":true} // Payload 2 {"data":{"cpu":"386","year":1993,"screen":{"resolution":"640x480"}},"path":["computers",0],"hasNext":true} // Payload 3 {"data":{"cpu":"486","year":1996,"screen":{"resolution":"640x480"}},"path":["computers",1],"hasNext":true} // Payload 4 {"data":{"isColor":false},"path":["computers",0,"screen"],"hasNext":true} // Payload 5 {"data":{"isColor":false},"path":["computers",1,"screen"],"hasNext":false} ``` -------------------------------- ### SDL Schema Definition Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/file-types.mdx Example of a GraphQL schema defined using Schema Definition Language (SDL). SDL is cleaner than JSON and supports directives, which are not present in the JSON representation. ```graphql type schema { query: Query mutation: Mutation } type Query { field: String @deprecated ... } ``` -------------------------------- ### JSON Response for Paginated Users Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/home.mdx Example JSON response for a paginated user list query. ```json { "data": { "usersPage": [ { "id": 1, "name": "John Smith" }, { "id": 2, "name": "Jane Doe" } ] } } ``` -------------------------------- ### GraphQL Query with Fragments Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Codegen.md Example GraphQL query demonstrating the use of inline and named fragments for fetching hero data. ```graphql query GetHero { hero { id name ... on Droid { name } ...droidDetails } } fragment droidDetails on Droid { name } ``` ```graphql query GetHero { hero { id ...droidDetails } } fragment droidDetails on Droid { primaryFunction } ``` ```graphql query GetHero { hero { id name ... on Droid { name } } } ``` ```graphql query TestOperation { something { ... on Type1 { #... } ... on Type2 { #... } ... on Type3 { #... } } } ``` -------------------------------- ### Define Book Schema Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/declarative-ids.mdx Example of a Book type definition in your backend schema. This serves as the basis for applying cache policies. ```graphql type Book { id: String! author: Author! title: String! } ``` -------------------------------- ### Register Apollo Client with Debug Server Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/testing/apollo-debug-server.mdx Call ApolloDebugServer.registerApolloClient to start the server and enable communication with the Android Studio plugin. This should be done within a debug build. ```kotlin val apolloClient = ApolloClient.Builder() // ... .build() if (BuildConfig.DEBUG) ApolloDebugServer.registerApolloClient(apolloClient) ``` -------------------------------- ### Define a GraphQL Mutation Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/mutations.mdx Define a mutation in a `.graphql` file using the `mutation` keyword. This example shows how to upvote a post. ```graphql mutation UpvotePost($postId: Int!) { upvotePost(postId: $postId) { id votes } } ``` -------------------------------- ### JSON Merging Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer merging implementation.md Demonstrates merging a JSON payload into an initial JSON structure using a specified path. This shows how nested objects and arrays are updated. ```json { "computers": [ { "__typename": "Computer", "id": "Computer1" }, { "__typename": "Computer", "id": "Computer2" } ] } ``` ```json { "cpu": "386", "year": 1993, "screen": { "resolution": "640x480" } } ``` ```json { "computers": [ { "__typename": "Computer", "id": "Computer1", "cpu": "386", "year": 1993, "screen": { "resolution": "640x480" } }, { "__typename": "Computer", "id": "Computer2" } ] } ``` -------------------------------- ### Get AST Document or Throw on Error Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/apollo-ast.mdx Safely retrieve the GQLDocument from a GQLResult, throwing an exception if any parsing errors occurred. Warnings may still be present alongside a valid document. ```kotlin val queryGqlDocument = parseResult.getOrThrow() ``` -------------------------------- ### GraphQL Query with Multiple Inline Fragments Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/migration/1.3.mdx An example GraphQL query demonstrating a scenario with multiple inline fragments (`... on Hero` and `... on Human`) that should be resolved for a given type. ```graphql query { character { name ... on Hero { ... } ... on Human { ... } } } ``` -------------------------------- ### GraphQL Query with @defer Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer draft API.md Example of a GraphQL query utilizing the @defer directive on a fragment. This demonstrates how specific fields can be deferred for later loading. ```graphql query Query { computers { cpu year ... on Computer @defer { id } } } ``` -------------------------------- ### Add ApolloClientAwarenessInterceptor to ApolloClient Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/client-awareness.mdx Enable Client Awareness by adding the `ApolloClientAwarenessInterceptor` to your `ApolloClient`. This example uses `BuildConfig` to set the client name and version, but these can be customized. ```kotlin val apolloClient = ApolloClient.Builder() .serverUrl("https://example.com/graphql") .addHttpInterceptor(ApolloClientAwarenessInterceptor(BuildConfig.APPLICATION_ID, BuildConfig.VERSION_NAME)) .build() ``` -------------------------------- ### Basic MockServer usage Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/testing/mocking-http-responses.mdx Create a MockServer instance, provide its URL to ApolloClient, enqueue responses, and execute queries. Remember to stop the server when done. ```kotlin // Create a mock server val mockServer = MockServer() // Provide its URL to your ApolloClient val apolloClient = ApolloClient.Builder().serverUrl(mockServer.url()).store(store).build() // Enqueue HTTP responses mockServer.enqueueString("{\"data\": {\"random\": 42}}") mockServer.enqueue( MockResponse( body = "Internal server error", statusCode = 500, headers = mapOf("X-Test" to "true"), // Optionally pass a delay to simulate network latency delayMillis = 1000L, ) ) // Execute queries val response1 = apolloClient .query(GetRandomQuery()) .execute() val response2 = apolloClient .query(GetRandomQuery()) .execute() // Don't forget to stop the server when you're done mockServer.stop() ``` -------------------------------- ### Operation Based Codegen Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/response-based.mdx Illustrates how operation-based codegen generates classes matching the GraphQL operation shape, including separate classes for fragments and nullable fields for conditional data. ```graphql query HeroForEpisode($ep: Episode!) { search { hero(episode: $ep) { name ... on Droid { name primaryFunction } ...HumanFields } } } fragment HumanFields on Human { height } ``` -------------------------------- ### Create File Upload Instance (Multiplatform) Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/upload.mdx Use `DefaultUpload.Builder` for multiplatform projects to construct an upload. Provide a filename and content stream. ```kotlin // On multiplatform, you can use `DefaultUpload` val upload = DefaultUpload.Builder() .fileName("filename.txt") .content { sink -> okioSource.use { sink.writeAll(it) } } .build() ``` -------------------------------- ### Monomorphic Field Example 1 Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Typename.md An example of a monomorphic field 'dog' where a fragment '... on Animal' is used. This is considered monomorphic because 'Animal' is a supertype of 'Dog'. ```graphql { # This is a monomorphic field dog { ... on Animal { ... on Node { id } } } } ``` -------------------------------- ### Monomorphic Interface Field Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Typename.md An example of an interface field 'animal' that is also monomorphic. In this case, __typename is not strictly required for parsing the fragment as the type is known. ```graphql { # This field is of interface type but is also monomorphic animal { name } } ``` -------------------------------- ### Polymorphic Field Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Typename.md An example of a polymorphic field 'animal' where __typename is required to correctly parse fragments like '... on Dog' because 'Dog' is not a supertype of 'Animal'. ```graphql { # This is a polymorphic field animal { # __typename will be added here # Dog is not a supertype of Animal ... on Dog { name } } } ``` -------------------------------- ### Instantiating Query with Optional Variables Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/operation-variables.mdx Demonstrates how to create instances of the generated query class by omitting variables, providing null values, or sending explicit values using the `Optional` type. ```kotlin // Omit values for both variables val query = GetTodosQuery(Optional.Absent, Optional.Absent) // Provide null for both variables val query = GetTodosQuery(Optional.Present(null), Optional.Present(null)) // Send explicit values for both variables val query = GetTodosQuery(Optional.Present(100), Optional.Present(0)) ``` -------------------------------- ### Example Incremental Data Emissions Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer draft API.md Illustrates the sequence of data emissions a collector might receive when using the incremental `toFlow()` API. Each emission represents a progressively more complete data set as deferred fragments are resolved. ```kotlin Data( computers=[ Computer( id=Computer1, computerFields=null ), Computer( id=Computer2, computerFields=null ) ] ) ``` ```kotlin Data( computers=[ Computer( id=Computer1, computerFields=ComputerFields( cpu=386, year=1993, screen=Screen( resolution=640x480, screenFields=null ) ) ), Computer( id=Computer2, computerFields=null ) ] ) ``` ```kotlin Data( computers=[ Computer( id=Computer1, computerFields=ComputerFields( cpu=386, year=1993, screen=Screen( resolution=640x480, screenFields=null ) ) ), Computer( id=Computer2, computerFields=ComputerFields( cpu=486, year=1996, screen=Screen( resolution=800x600, screenFields=null ) ) ) ] ) ``` ```kotlin Data( computers=[ Computer( id=Computer1, computerFields=ComputerFields( cpu=386, year=1993, screen=Screen( resolution=640x480, screenFields=ScreenFields( isColor=false ) ) ) ), Computer( id=Computer2, computerFields=ComputerFields( cpu=486, year=1996, screen=Screen( resolution=800x600, screenFields=null ) ) ) ] ) ``` ```kotlin Data( computers=[ Computer( id=Computer1, computerFields=ComputerFields( cpu=386, year=1993, screen=Screen( resolution=640x480, screenFields=ScreenFields( isColor=false ) ) ) ), Computer( id=Computer2, computerFields=ComputerFields( cpu=486, year=1996, screen=Screen( resolution=800x600, screenFields=ScreenFields( isColor=false ) ) ) ) ] ) ``` -------------------------------- ### Prepare Next Release Script Source: https://github.com/apollographql/apollo-kotlin/blob/main/CONTRIBUTING.md Use this script to prepare for the next release by updating version numbers across the repository. Ensure the version always ends with '-SNAPSHOT'. ```bash ./scripts/update-repo.main.kts prepare-next-version ``` -------------------------------- ### Introspection Schema JSON Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/file-types.mdx Example of a GraphQL schema obtained via introspection query, provided in JSON format. Apollo Kotlin supports schemas with or without the top-level 'data' field. ```json { "data": { "__schema": { "queryType": { "name": "Query" }, "mutationType": { "name": "Mutation" }, "types": [...] } } } ``` -------------------------------- ### Apollo Client Initialization with Cache Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/relay-style.mdx Initializes the Apollo Client with a cache factory, essential for enabling features like Relay-style pagination. ```kotlin val client = ApolloClient.Builder() // ... .cache(cacheFactory) .build() ``` -------------------------------- ### Monomorphic Field Example 2 Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Typename.md Another example of a monomorphic field 'dog'. Here, '... on Animal' is used within '... on Node'. This is monomorphic because 'Animal' is a supertype of 'Dog', even though 'Animal' is not a supertype of 'Node'. ```graphql { # This is also monomorphic dog { ... on Node { # Animal is not a supertype of Node but it's a supertype of Dog ... on Animal { id } } } } ``` -------------------------------- ### Add Apollo Previews Repository Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/index.mdx Configure your build to use the Apollo previews repository for nightly builds. Replace -SNAPSHOT with the desired date for specific versions. This is configured in build.gradle.kts and settings.gradle.kts. ```kotlin // build.gradle.kts repositories { maven { url = uri("https://storage.googleapis.com/apollo-previews/m2/") } mavenCentral() // other repositories... } // settings.gradle.kts pluginManagement { repositories { maven { url = uri("https://storage.googleapis.com/apollo-previews/m2/") } mavenCentral() // other repositories... } } ``` -------------------------------- ### Build Mock Data for HeroForEpisode Query Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/testing/data-builders.mdx Demonstrates how to use generated data builders to construct a mock `HeroForEpisodeQuery.Data` object. It shows how to build nested objects like `hero`, `ship`, and `friends`, including fragment types like `Human` and `Droid`. ```kotlin @Test fun test() { val data = HeroForEpisodeQuery.Data { // Set values for particular fields of the query hero = buildHuman { firstName = "John" age = 42 friends = listOf( buildHuman { firstName = "Jane" }, buildHuman { lastName = "Doe" } ) ship = buildStarship { model = "X-Wing" } } } assertEquals("John", data.hero.firstName) assertEquals(42, data.hero.age) } ``` -------------------------------- ### GraphQL Schema for Mutation Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/mutations.mdx Example schema snippet defining the `Mutation` type and the `upvotePost` field. ```graphql type Mutation { upvotePost(postId: Int!): Post } type Post { id: Int! votes: Int! content: String! } ``` -------------------------------- ### ApolloStore Methods Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Normalized cache overview.md These are the main methods provided by the `ApolloStore` interface for interacting with the normalized cache at the operation and fragment level. ```kotlin readOperation(operation: Operation): D ``` ```kotlin readFragment(fragment: Fragment): D ``` ```kotlin writeOperation(operation: Operation, operationData: D): Set ``` ```kotlin writeFragment(fragment: Fragment, cacheKey: CacheKey, fragmentData: D): Set ``` -------------------------------- ### Run Macro and Microbenchmarks Source: https://github.com/apollographql/apollo-kotlin/blob/main/benchmark/README.md Execute macrobenchmarks or microbenchmarks using Gradle commands. Macrobenchmarks are run with `connectedBenchmarkAndroidTest`, and microbenchmarks with `benchmarkReport`. ```bash # macrobenchmarks ./gradlew -p benchmark :macrobenchmark:connectedBenchmarkAndroidTest # microbenchmarks ./gradlew -p benchmark :microbenchmark:benchmarkReport ``` -------------------------------- ### GraphQL Query for Paginated Users Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/home.mdx Example GraphQL query to fetch a paginated list of users. ```graphql query UsersPage($page: Int!) { usersPage(groupId: 2, page: $page) { id name } } ``` -------------------------------- ### Apollo Client Cache Configuration Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/compiler-plugin.mdx Demonstrates how to configure the ApolloClient builder with a cache using the generated cache() extension function. Optionally, defaultMaxAge and keyScope can be provided. ```kotlin val apolloClient = ApolloClient.Builder() // ... .cache(cacheFactory = /*...*/) .build() ``` -------------------------------- ### GraphQL Query without __typename Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Typename.md Example of a GraphQL query where __typename is not explicitly added to the selection set. ```graphql query Foo { foo { bar baz } } ``` -------------------------------- ### Run All Gradle Tests Source: https://github.com/apollographql/apollo-kotlin/blob/main/CONTRIBUTING.md Execute all Gradle tests for the project. This command builds the entire project and runs its associated tests. ```bash ./gradlew build ``` -------------------------------- ### GraphQL Schema Definition Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Defer merging implementation.md Defines the types and relationships for the example query, including Computer and Screen with nested fields. ```graphql type Query { computers: [Computer!]! } type Computer { id: ID! cpu: String! year: Int! screen: Screen! } type Screen { resolution: String! isColor: Boolean! } ``` -------------------------------- ### Run Integration Tests Source: https://github.com/apollographql/apollo-kotlin/blob/main/CONTRIBUTING.md Execute integration tests located in the 'tests' composite build. This is often faster than running all Gradle tests and is recommended for most integration testing scenarios. ```bash ./gradlew -p tests build ``` -------------------------------- ### Accessing ApolloStore Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/store.mdx Get the ApolloStore instance from an ApolloClient. Note that read/write operations are synchronous and should not be called from the main thread. ```kotlin val apolloClient = ApolloClient.Builder() .serverUrl("https://example.com/graphql") .cache(MemoryCacheFactory(maxSizeBytes = 10 * 1024 * 1024)) .build() val apolloStore: ApolloStore = apolloClient.apolloStore ``` -------------------------------- ### GraphQL Query for Relay-style Pagination Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/relay-style.mdx A sample GraphQL query demonstrating how to fetch paginated data using Relay-style arguments. ```graphql query UsersConnection($first: Int, $after: String, $last: Int, $before: String) { usersConnection(first: $first, after: $after, last: $last, before: $before) { edges { cursor node { name } } pageInfo { hasNextPage endCursor } } } ``` -------------------------------- ### Mutation with Input Object Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/mutations.mdx Define a mutation that accepts complex input objects. This example shows creating a review for an episode. ```graphql mutation CreateReviewForEpisode($episode: Episode!, $review: ReviewInput!) { createReview(episode: $episode, review: $review) { stars commentary } } ``` -------------------------------- ### Custom FieldRecordMerger Implementation Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/pagination/other.mdx Implement `FieldRecordMerger.FieldMerger` to define how lists are merged. This example simply concatenates existing and incoming lists. ```kotlin object MyFieldMerger : FieldRecordMerger.FieldMerger { override fun mergeFields(existing: FieldRecordMerger.FieldInfo, incoming: FieldRecordMerger.FieldInfo): FieldRecordMerger.FieldInfo { val existingList = existing.value as List<*> val incomingList = incoming.value as List<*> val mergedList = existingList + incomingList return FieldRecordMerger.FieldInfo( value = mergedList, metadata = emptyMap() ) } } ``` ```kotlin val client = ApolloClient.Builder() // ... .normalizedCache( normalizedCacheFactory = cacheFactory, recordMerger = FieldRecordMerger(MyFieldMerger), // Configure the store with the custom merger ) .build() ``` -------------------------------- ### Configure ApolloClient with QueueTestNetworkTransport Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/testing/mocking-graphql-responses.mdx Enable `QueueTestNetworkTransport` by passing it to the `ApolloClient.Builder` to manage mocked responses. ```kotlin val apolloClient = ApolloClient.Builder() .networkTransport(QueueTestNetworkTransport()) .build() ``` -------------------------------- ### Map CacheFirst to OkHttp Default Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/migration/5.0.mdx The `CacheFirst` fetch policy is now the default behavior when using OkHttp's cache. No explicit header is needed. ```kotlin // Replace apolloClient.query(query).httpFetchPolicy(HttpFetchPolicy.CacheFirst) // With apolloClient.query(query) // no need to add a cache-control header, this is the default ``` -------------------------------- ### Parse and Validate Schema Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/apollo-ast.mdx Parses a GraphQL schema string and validates it. This example demonstrates validating an invalid schema with an undefined directive. ```kotlin val schemaText = """ type Query { hero(episode: Episode): Character } enum Episode { NEWHOPE EMPIRE } type Character @private { name: String height: Int @deprecated friends: [Character] } """.trimIndent() val schemaGQLDocument = schemaText.parseAsGQLDocument().getOrThrow() val schemaResult = schemaGQLDocument.validateAsSchema() println(schemaResult.issues.map { it.severity.name + ": " + it.message }) ``` -------------------------------- ### Create File Upload Instance (Android/JVM) Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/upload.mdx Convert a `File` object into an upload instance for Android or JVM projects. Specify the MIME type as needed. ```kotlin // If you're on Android/JVM, you can turn a File into an upload val upload = File.toUpload("application/json") ``` -------------------------------- ### Configure Introspection Schema Download Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/plugin-configuration.mdx Set up the introspection schema download by providing the GraphQL endpoint URL and the local schema file path. ```kotlin introspection { endpointUrl.set("https://your.domain/graphql/endpoint") schemaFile.set(file("src/main/graphql/com/example/schema.graphqls")) } ``` -------------------------------- ### Response-Based Codegen: Merged Fields Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Codegen.md Illustrates how merged fields from fragments are handled in response-based codegen, appearing once in the model tree. ```kotlin // name is queried in three different positions but will appear either in the Droid shape or // in the OtherHero shape: // If the response is a Droid (data.hero as Droid).name // If the response is of another type (data.hero as OtherHero).name // Because both Droid and OtherHero inherit from Hero and name is queried directly on hero, // name is also accessible from the interface. // This specific example is contrived because accessing this way is always easier but it // shows the multiple possibilities. data.hero.name ``` -------------------------------- ### Configure Schema and GraphQL Files Location (Groovy DSL) Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/migration/1.3.mdx Migrate schema file path and exclude patterns to the new `schemaFile` and `graphqlSourceDirectorySet.exclude` properties within the `apollo.service` block. ```groovy // Replace apollo { service("service") { sourceSet { schemaFilePath = "/path/to/your/schema.json" exclude = "**/*.gql" } outputPackageName = "com.example" } } // With: apollo { service("service") { schemaFile.set(file("/path/to/your/schema.json")) graphqlSourceDirectorySet.exclude("**/*.gql") packageName.set("com.example") } } ``` -------------------------------- ### Execute a Query with ApolloClient Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/queries.mdx Instantiate ApolloClient and use its query method to execute a defined query. The execute() method runs the query and returns the response. ```kotlin val apolloClient = ApolloClient.Builder().serverUrl("https://example.com/graphql").build() val response = apolloClient.query(HeroQuery(id = "12")).execute() ``` -------------------------------- ### GraphQL Query with Named Fragment Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Codegen.md Example of a GraphQL query that includes a named fragment for fetching hero details and droid-specific information. ```graphql query GetHero { hero { id ...droidDetails } } fragment droidDetails on Droid { primaryFunction } ``` -------------------------------- ### Add Maven Central Snapshots Repository Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/index.mdx Configure your build to use Maven Central's snapshots repository for the latest development changes. This is typically done in build.gradle.kts and settings.gradle.kts. ```kotlin // build.gradle.kts repositories { maven { url = uri("https://central.sonatype.com/repository/maven-snapshots/") } mavenCentral() // other repositories... } // settings.gradle.kts pluginManagement { repositories { maven { url = uri("https://central.sonatype.com/repository/maven-snapshots/") } mavenCentral() // other repositories... } } ``` -------------------------------- ### Basic Apollo Compiler Plugin Implementation Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/compiler-plugins.mdx Implement the `ApolloCompilerPlugin` interface and override `beforeCompilationStep` to add custom logic. ```kotlin class MyPlugin: ApolloCompilerPlugin { override fun beforeCompilationStep( environment: ApolloCompilerPluginEnvironment, registry: ApolloCompilerRegistry, ) { // add your custom code here } } ``` -------------------------------- ### GraphQL Query with Inline Fragment Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Codegen.md Example of a GraphQL query using an inline fragment to conditionally fetch fields based on the hero's type. ```graphql query GetHero { hero { id ... on Droid { name } } } ``` -------------------------------- ### Data Root Function Extension Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/migration/5.0.mdx The root function for building `Data` instances, `Data {}`, is now an extension function. You need to import it from the `com.example.builder` package. ```kotlin // Add import com.example.builder.Data ``` -------------------------------- ### Configure HTTP Cache with OkHttp Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/http-cache.mdx Enable POST request caching by configuring the `NetworkTransport` with a cache-enabled `OkHttpClient` and setting `enablePostCaching` to `true`. ```kotlin val apolloClient = ApolloClient.Builder() .networkTransport( HttpNetworkTransport.Builder() // Enable POST caching .httpRequestComposer(DefaultHttpRequestComposer(serverUrl = serverUrl, enablePostCaching = true)) .httpEngine( DefaultHttpEngine { OkHttpClient.Builder() .cache(directory = File(application.cacheDir, "http_cache"), maxSize = 10_000_000) .build() } ) .build() ) .build() ``` -------------------------------- ### Update Import Statements for MockServer Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/migration/4.0.mdx When migrating to new artifact coordinates, you may need to update your import statements. This example shows how to change the import for MockServer. ```kotlin // Replace import com.apollographql.apollo3.mockserver.MockServer // With import com.apollographql.mockserver.MockServer ``` -------------------------------- ### GraphQL Query with Null Field Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Codegen.md A GraphQL query that includes a field named 'null'. This example demonstrates how Apollo Kotlin handles Kotlin reserved keywords. ```graphql { hero { null } } ``` -------------------------------- ### Configure Apollo Gradle Plugin Options Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/plugin-configuration.mdx This block shows all available options for the Apollo Gradle Plugin within a single configuration. Refer to the ApolloExtension and Service API references for detailed explanations of each option. ```kotlin apollo { service("service") { // The package name for the generated models packageName.set("com.example") // Adds the given directory as a GraphQL source root srcDir("src/main/graphql") // Operation files to include. includes.add("**/*.graphql") // Operation files to exclude. excludes.add("**/*.graphqls") // Explicitly set the schema schemaFiles.from("src/main/graphql/schema.graphqls") // Extend your schema locally with type extensions schemaFiles.from("shared/graphql/schema.graphqls", "shared/graphql/extra.graphqls") // What codegen to use. One of "operationBased", "responseBased" codegenModels.set("operationBased") // Warn if using a deprecated field warnOnDeprecatedUsages.set(true) // Fail on warnings failOnWarnings.set(true) // Map the "Date" custom scalar to the com.example.Date Kotlin type mapScalar("Date", "com.example.Date") // Shorthands to map scalar to builtin types and configure their adapter at build time mapScalarToUpload("Upload") mapScalarToKotlinString("MyString") mapScalarToKotlinInt("MyInt") mapScalarToKotlinDouble("MyDouble") mapScalarToKotlinFloat("MyFloat") mapScalarToKotlinLong("MyLong") mapScalarToKotlinBoolean("MyBoolean") mapScalarToKotlinAny("MyAny") mapScalarToJavaString("MyString") mapScalarToJavaInteger("MyInteger") mapScalarToJavaDouble("MyDouble") mapScalarToJavaFloat("MyFloat") mapScalarToJavaLong("MyLong") mapScalarToJavaBoolean("MyBoolean") mapScalarToJavaObject("MyObject") // The format to output for the operation manifest. One of "none" (default) or "persistedQueryManifest" operationManifestFormat.set("persistedQueryManifest") // Whether to generate Kotlin or Java models generateKotlinModels.set(true) // Target language version for the generated code. languageVersion.set("1.5") // Whether to suffix operation name with 'Query', 'Mutation' or 'Subscription' useSemanticNaming.set(true) // Whether to generate kotlin constructors with `@JvmOverloads` for more graceful Java interop experience when default values are present. addJvmOverloads.set(true) // Whether to generate Kotlin models with `internal` visibility modifier. generateAsInternal.set(true) // Whether to generate default implementation classes for GraphQL fragments. generateFragmentImplementations.set(true) // Whether to write the query document in models generateQueryDocument.set(true) // Whether to generate the Schema class. generateSchema.set(true) // Name for the generated schema generatedSchemaName.set("Schema") // Whether to generate operation variables as [com.apollographql.apollo.api.Optional] generateOptionalOperationVariables.set(true) // Whether to generate the type safe Data builders. generateDataBuilders.set(true) // Whether to generate response model builders for Java. generateModelBuilders.set(true) // Which methods to auto generate (can include: `equalsHashCode`, `copy`, `toString`, or `dataClass`) generateMethods.set(listOf("dataClass")) // Whether to generate fields as primitive types (`int`, `double`, `boolean`) instead of their boxed types (`Integer`, `Double`, etc..) generatePrimitiveTypes.set(true) // Opt-in Builders for Operations, Fragments and Input types. Builders are more ergonomic than default arguments when there are a lot of // optional arguments. generateInputBuilders.set(true) // The style to use for fields that are nullable in the Java generated code nullableFieldStyle.set("apolloOptional") // Whether to decapitalize field names in the generated models (for instance `FooBar` -> `fooBar`) decapitalizeFields.set(false) // Whether to add the [JsExport] annotation to generated models. jsExport.set(true) // When to add __typename. addTypename.set("always") // Whether to flatten the models. File paths are limited on MacOSX to 256 chars and flattening can help keeping the path length manageable flattenModels.set(true) // A list of [Regex] patterns for GraphQL enums that should be generated as Kotlin sealed classes instead of the default Kotlin enums. sealedClassesForEnumsMatching.set(listOf(".*")) // A list of [Regex] patterns for GraphQL enums that should be generated as Java classes. } } ``` -------------------------------- ### Output GQLDocument to SDL File Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/apollo-ast.mdx Serializes a GQLDocument AST into its equivalent GraphQL Schema Definition Language (SDL) string representation and writes it to a specified file. Useful for saving schema definitions. ```kotlin queryGqlDocument.toUtf8(file) ``` -------------------------------- ### GraphQL Query for Hero Name Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/Codegen.md A simple GraphQL query to fetch the 'name' field of a 'hero'. This example is used to illustrate Kotlin model naming conventions. ```graphql { hero { name } } ``` -------------------------------- ### Create all Android variant services Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/plugin-recipes.mdx Automatically configure an Apollo Service for each Android variant, specifying the source folder and an optional name suffix. ```kotlin apollo { createAllAndroidVariantServices(sourceFolder = ".", nameSuffix = "") { // Configure the service here packageName.set("...") } } ``` -------------------------------- ### Customize Retry Behavior with RetryStrategy Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/network-errors.mdx Implement a custom `RetryStrategy` to define specific retry conditions and delays. This example waits 10 seconds before retrying an operation. ```kotlin val apolloClient = ApolloClient.Builder() .retryOnErrorInterceptor(RetryOnErrorInterceptor(networkMonitor) { state, request, response -> val exception = response.exception if (exception == null) { // No error, do not retry return@RetryOnErrorInterceptor false } delay(10.seconds) return@RetryOnErrorInterceptor true }) .build() ``` -------------------------------- ### ApolloResponse with Exception Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/design-docs/ApolloResult.md Illustrates an `ApolloResponse` object that contains both data and an exception. Note that the type system allows this state, which might be considered an impossible state. ```kotlin ApolloResponse( data = SomeData(), // Not possible but the type system allows it exception = IOException() ) ``` -------------------------------- ### Download Schema from GraphOS Registry Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/plugin-recipes.mdx Configure the plugin to download the GraphQL schema from the GraphOS registry. Requires API key and graph ID, which can be set via environment variables. The schema file path is relative to the project. ```kotlin apollo { service("starwars") { packageName.set("com.starwars") // This creates a downloadStarwarsApolloSchemaFromRegistry task registry { key.set(System.getenv("APOLLO_KEY")) graph.set(System.getenv("APOLLO_GRAPH")) // The path is interpreted relative to the current project here, no need to prepend 'app' schemaFile.set(file("src/main/graphql/com/example/schema.graphqls")) } } } ``` -------------------------------- ### Fragment Builder Reference Update Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/migration/5.0.mdx For fragments, concrete object builders are no longer companion objects. You must now reference them explicitly, for example, using `LionBuilder` instead of `Lion`. ```kotlin // Replace val data = AnimalDetailsImpl.Data(Lion) { /* ... */ } // With val data = AnimalDetailsImpl.Data(LionBuilder) { /* ... */ } ``` -------------------------------- ### Validate Executable Document Against Schema Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/apollo-ast.mdx Validates a GraphQL operation document against a provided schema. This example shows how to check for issues like querying deprecated fields or typos. ```kotlin val schema = schemaGQLDocument.validateAsSchema().getOrThrow() val executableIssues = queryGqlDocument.validateAsExecutable(schema) println(executableIssues.map { it.severity.name + ": " + it.message }) ``` -------------------------------- ### Configuring Test Fixtures for Multi-Module Projects Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/testing/data-builders.mdx For multi-module projects, apply the `java-test-fixtures` plugin and connect data builder sources to the `testFixtures` source set to enable sharing between modules. ```kotlin plugins { id("org.jetbrains.kotlin.jvm") id("com.apollographql.apollo") id("java-test-fixtures") } apollo { service("service") { dataBuildersOutputDirConnection { connectToKotlinSourceSet("testFixtures") // highlight-line } } } ``` -------------------------------- ### Listen to a Subscription Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/essentials/subscriptions.mdx Demonstrates how to listen for changes from a GraphQL subscription using Apollo Kotlin. It converts the subscription to a Kotlin Flow for continuous updates. ```kotlin apolloClient.subscription(TripsBookedSubscription()) .toFlow() .collect { println("trips booked: ${it.data?.tripsBooked}") } ``` -------------------------------- ### Custom Operation ID Generation with Compiler Plugin Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/persisted-queries.mdx Implement a custom operation ID generator by overriding the `operationIds()` method in an `ApolloCompilerPlugin`. This example uses MD5 hashing. ```kotlin class MyPlugin : ApolloCompilerPlugin { override fun beforeCompilationStep( environment: ApolloCompilerPluginEnvironment, registry: ApolloCompilerRegistry, ) { registry.registerOperationIdsGenerator { it.map { OperationId(it.source.md5(), it.name) } } } } ``` -------------------------------- ### Using Fragments with Concrete Types Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/testing/data-builders.mdx When using fragments defined on interfaces or unions, explicitly specify the concrete type you want to model. This example creates a `Lion` fragment data builder. ```kotlin val data = AnimalDetailsImpl.Data(LionBuilder) { // you can access roar here roar = "Grrrrr" } ``` -------------------------------- ### Implement a Custom HttpEngine Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/http-engine.mdx Implement the `HttpEngine` interface to integrate a custom HTTP client. The `execute` method handles network requests, and `close` is for resource cleanup. Helper methods can be added for request/response mapping. ```kotlin class MyHttpEngine(val wrappedClient: MyClient) : HttpEngine { /** * Helper function to map the Apollo requests to MyClient requests */ private fun HttpMethod.toMyClientRequest(): MyClientRequest { ... } /** * And the other way around */ private fun MyClientResponse.toApolloResponse(): HttpResponse { ... } override suspend fun execute(request: HttpRequest) = suspendCancellableCoroutine { continuation -> val call = wrappedClient.newCall(request.toMyClientRequest()) continuation.invokeOnCancellation { // If the coroutine is cancelled, also cancel the HTTP call call.cancel() } wrappedClient.enqueue( call, success = { myResponse -> // Success! report the response continuation.resume(myResponse.toApolloResponse()) }, error = { throwable -> // Error. Wrap in an ApolloException and report the error continuation.resumeWithException(ApolloNetworkException(throwable)) } ) } override fun close() { // Dispose any resources here } } ``` -------------------------------- ### GraphQL Query for Cache ID Example Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/caching/normalized-cache.mdx This GraphQL query demonstrates fetching a book and its author, illustrating how Apollo Kotlin generates default cache IDs based on field paths. ```graphql query GetFavoriteBook { favoriteBook { # Book object id title author { # Author object id name } } } ``` -------------------------------- ### Configure multiple GraphQL services Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/plugin-recipes.mdx Define multiple Apollo services, each with its own source directory and package name, to communicate with different GraphQL APIs. ```kotlin apollo { service("starwars") { srcDir("src/main/graphql/starwars") packageName.set("com.starwars") } service("githunt") { srcDir("src/main/graphql/githunt") packageName.set("com.githunt") } } ``` -------------------------------- ### Generated Kotlin Models for Basic Query Source: https://github.com/apollographql/apollo-kotlin/blob/main/docs/source/advanced/using-aliases.mdx This is an example of the Kotlin data classes that Apollo Kotlin might generate for a simple GraphQL query, illustrating the flat hierarchy and naming conventions. ```kotlin class GetContact { class Data { ... } class Contact { ... } class HomeAddress { ... } class WorkAddress { ... } } ```