A full usage example can be found in the test project
- Add the apollo runtime library to your project's dependencies:
<dependencies>
<dependency>
<groupId>com.apollographql.apollo</groupId>
<artifactId>apollo-runtime</artifactId>
<version>2.2.0</version>
</dependency>
<!-- Optional, needed only for ANNOTATED nullable type-->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>19.0.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>1.3.72</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.2.0</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.json
with the JSON results of an introspection query OR you can automatically generate this file by settinggenerateIntrospectionFile
to true andschemaUrl
to 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/graphql
are treated as extra package names to append topackageName
in the plugin config.
- Run
mvn clean generate-sources
to generate classes for your queries.
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>
<customTypeMap></customTypeMap>
<enumAsSealedClassPatternFilters></enumAsSealedClassPatternFilters>
</configuration>
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.
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>
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
Response intercept(Interceptor.Chain chain) throws IOException {
chain.proceed(chain.request().newBuilder().addHeader("Authorization", "Basic cnllYnJ5ZTpidWJibGVzMTIz").build())
}
})
.build())
.build()
client.newCall(new GetBooks())
.enqueue(new ApolloCall.Callback<GetBooks.Data>() {
@Override public void onResponse(@NotNull Response<GetBooks.Data> response) {
...
}
@Override public void onFailure(@NotNull ApolloException t) {
...
}
});
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;
}
}
See documentation