Apollo GraphQL Client Code Generation Maven Plugin
Usage
A full usage example can be found in the test project
Getting Started
- Add the apollo runtime library to your project's dependencies:
<dependencies>
   <dependency>
       <groupId>com.apollographql.apollo</groupId>
       <artifactId>apollo-runtime</artifactId>
       <version>2.3.1</version>
   </dependency>
    <dependency>
        <groupId>com.squareup.okio</groupId>
        <artifactId>okio</artifactId>
        <version>2.8.0</version>
    </dependency>
   <!-- Optional, needed only for ANNOTATED nullable type-->
   <dependency>
       <groupId>org.jetbrains</groupId>
       <artifactId>annotations</artifactId>
       <version>20.1.0</version>
   </dependency>
   <dependency>
       <groupId>org.jetbrains.kotlin</groupId>
       <artifactId>kotlin-reflect</artifactId>
       <version>1.4.0</version>
   </dependency>
</dependencies> 
- Add the code generator plugin to your project's build:
<plugin>
    <groupId>com.github.sparow199</groupId>
    <artifactId>apollo-client-maven-plugin</artifactId>
    <version>3.3.1</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                    <rootPackageName>com.example.graphql.client</rootPackageName>
            </configuration>
        </execution>
    </executions>
</plugin> 
- Create a file src/main/graphql/schema.jsonwith the JSON results of an introspection query OR you can automatically generate this file by settinggenerateIntrospectionFileto true andschemaUrlto your GraphQL endpoint. At build time, the plugin will query the server and install this file per the value ofintrospectionFile.
- Create files for each query you'd like to generate classes for under src/main/graphql:- Query file names must match the name of the query they contain
- Query files must end with .graphql
- Any subdirectories under src/main/graphqlare treated as extra package names to append torootPackageNamein the plugin config.
 
- Run mvn clean generate-sourcesto generate classes for your queries.
Configuration Options
All plugin options and their defaults:
<configuration>
    <skip>false</skip>
    <addSourceRoot>true</addSourceRoot>
    <introspectionFile>${project.basedir}/src/main/graphql/schema.json</introspectionFile>
    <generateIntrospectionFile>false</generateIntrospectionFile>
    <sourceDirName>${project.basedir}/src/main/graphql</sourceDirName>
    <schemaUrl>http://localhost/graphql</schemaUrl>
    <schemaUrlHeaders></schemaUrlHeaders>
    <useSelfSignedCertificat>false</useSelfSignedCertificat>
    <rootPackageName>com.example.graphql.client</rootPackageName>
    <outputDirectory>${project.build.directory}/generated-sources/graphql-client</outputDirectory>
    <operationIdGeneratorClass>com.apollographql.apollo.compiler.OperationIdGenerator$Sha256</operationIdGeneratorClass>
    <generateModelBuilder>true</generateModelBuilder>
    <useJavaBeansSemanticNaming>true</useJavaBeansSemanticNaming>
    <useSemanticNaming>true</useSemanticNaming>
    <nullableValueType>JAVA_OPTIONAL</nullableValueType>
    <suppressRawTypesWarning>false</suppressRawTypesWarning>
    <generateKotlinModels>false</generateKotlinModels>
    <generateAsInternal>false</generateAsInternal>
    <generateVisitorForPolymorphicDatatypes>false</generateVisitorForPolymorphicDatatypes>
    <kotlinMultiPlatformProject>false</kotlinMultiPlatformProject>
    <customTypeMap></customTypeMap>
    <enumAsSealedClassPatternFilters></enumAsSealedClassPatternFilters>
</configuration> 
Nullable Types
Available nullable types:
ANNOTATED
APOLLO_OPTIONAL
GUAVA_OPTIONAL
JAVA_OPTIONAL
INPUT_TYPE
Properties specified as nullable in the schema will have a java 8 java.util.optional type.
Custom Types
To use the Custom Scalar Types you need to define mapping configuration then register your custom adapter:
<configuration>
    ...
    <customTypeMap>
        <Long>java.lang.Long</Long>
    </customTypeMap>
</configuration> 
Using Apollo Client
Assuming a file named src/main/graphql/GetBooks.graphql is defined that contains a query named GetBooks against the given schema.json, the following code demonstrates how that query could be executed.
ApolloClient client = ApolloClient.builder()
    .serverUrl("https://example.com/graphql")
    .okHttpClient(new OkHttpClient.Builder()
        .addInterceptor(new Interceptor() {
            @Override
            okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
                return chain.proceed(chain.request().newBuilder().addHeader("Authorization", "Basic cnllYnJ5ZTpidWJibGVzMTIz").build());
            }
        })
        .build())
    .build();
client.query(new GetBooksQuery())
    .enqueue(new ApolloCall.Callback<GetBooksQuery.Data>() {
    @Override public void onResponse(@NotNull Response<GetBooksQuery.Data> response) {
        ...
    }
    @Override public void onFailure(@NotNull ApolloException t) {
        ...
    }
    }); 
Wrap ApolloCall with CompletableFuture
If you miss apolloCall.execute method, which execute a query synchronously, you could wrap apolloCall.enqueue with a CompletableFuture and call join method to wait for the response
public class ApolloClientUtils {
    public static <T> CompletableFuture<Response<T>> toCompletableFuture(ApolloCall<T> apolloCall) {
        CompletableFuture<Response<T>> completableFuture = new CompletableFuture<>();
        completableFuture.whenComplete((tResponse, throwable) -> {
            if (completableFuture.isCancelled()) {
                completableFuture.cancel(true);
            }
        });
        apolloCall.enqueue(new ApolloCall.Callback<T>() {
            @Override
            public void onResponse(@NotNull Response<T> response) {
                completableFuture.complete(response);
            }
            @Override
            public void onFailure(@NotNull ApolloException e) {
                completableFuture.completeExceptionally(e);
            }
        });
        return completableFuture;
    }
} 
Using Apollo without apollo-runtime
 
See documentation
 JarCasting
 JarCasting