Skip to main content

Gradle Integration

Integrate the GraphQL Code Generator into your Gradle build process to automatically generate code whenever your schema changes.

Basic Setup

1
plugins {
2
id 'java'
3
}
4
5
// Define source sets for generated code
6
sourceSets {
7
main {
8
java {
9
srcDir 'src/main/java'
10
srcDir 'build/generated/graphql'
11
}
12
}
13
}
14
15
// Task to run code generator
16
tasks.register('generateGraphQLCode', JavaExec) {
17
group = 'code generation'
18
description = 'Generates GraphQL schema code'
19
20
classpath = sourceSets.main.runtimeClasspath
21
mainClass = 'com.example.codegen.BlogCodeGenerator'
22
23
inputs.files(fileTree('src/main/resources/graphql'))
24
outputs.dir('build/generated/graphql')
25
}
26
27
// Ensure code generation runs before compilation
28
tasks.named('compileJava') {
29
dependsOn('generateGraphQLCode')
30
}
31
32
// Clean generated code on clean
33
tasks.named('clean') {
34
delete 'build/generated'
35
}
36
37
dependencies {
38
// The GraphQL plugin provides both the code generator and the runtime framework
39
implementation 'com.brightspot.graphql:graphql'
40
}
41

How It Works

  1. sourceSets - Adds the generated sources directory to your Java source sets so the compiler can find them
  2. generateGraphQLCode task - Runs your code generator wrapper class
  3. inputs.files / outputs.dir - Gradle up-to-date checking (only regenerates when schema changes)
  4. compileJava.dependsOn - Ensures code generation runs before compilation

Multiple GraphQL APIs

If you have multiple GraphQL schemas in the same project, create separate tasks:

1
tasks.register('generateUserAPI', JavaExec) {
2
classpath = sourceSets.main.runtimeClasspath
3
mainClass = 'com.example.codegen.UserAPICodeGenerator'
4
5
inputs.file('src/main/resources/graphql/user-api.graphql')
6
outputs.dir('build/generated/graphql')
7
}
8
9
tasks.register('generateAdminAPI', JavaExec) {
10
classpath = sourceSets.main.runtimeClasspath
11
mainClass = 'com.example.codegen.AdminAPICodeGenerator'
12
13
inputs.file('src/main/resources/graphql/admin-api.graphql')
14
outputs.dir('build/generated/graphql')
15
}
16
17
tasks.register('generateAllAPIs') {
18
dependsOn('generateUserAPI', 'generateAdminAPI')
19
}
20
21
tasks.named('compileJava') {
22
dependsOn('generateAllAPIs')
23
}

Multi-Module Projects

For projects with separate schema modules:

1
sourceSets {
2
main {
3
java {
4
srcDir 'src/main/java'
5
srcDir 'build/generated/graphql/public'
6
srcDir 'build/generated/graphql/admin'
7
srcDir 'build/generated/graphql/internal'
8
}
9
}
10
}
11
12
tasks.register('generatePublicAPICode', JavaExec) {
13
classpath = sourceSets.main.runtimeClasspath
14
mainClass = 'com.example.codegen.PublicAPICodeGenerator'
15
inputs.files(fileTree('graphql-schemas/public-api'))
16
outputs.dir('build/generated/graphql/public')
17
}
18
19
tasks.register('generateAdminAPICode', JavaExec) {
20
classpath = sourceSets.main.runtimeClasspath
21
mainClass = 'com.example.codegen.AdminAPICodeGenerator'
22
inputs.files(fileTree('graphql-schemas/admin-api'))
23
outputs.dir('build/generated/graphql/admin')
24
}
25
26
tasks.register('generateInternalAPICode', JavaExec) {
27
classpath = sourceSets.main.runtimeClasspath
28
mainClass = 'com.example.codegen.InternalAPICodeGenerator'
29
inputs.files(fileTree('graphql-schemas/internal-api'))
30
outputs.dir('build/generated/graphql/internal')
31
}
32
33
tasks.register('generateAllGraphQLCode') {
34
dependsOn('generatePublicAPICode', 'generateAdminAPICode', 'generateInternalAPICode')
35
}
36
37
tasks.named('compileJava') {
38
dependsOn('generateAllGraphQLCode')
39
}
40

Gradle Plugin (Alternative)

If you prefer a Gradle plugin approach, you can create a custom plugin:

1
// buildSrc/src/main/groovy/GraphQLCodeGenPlugin.groovy
2
import org.gradle.api.Plugin
3
import org.gradle.api.Project
4
5
class GraphQLCodeGenPlugin implements Plugin<Project> {
6
void apply(Project project) {
7
def extension = project.extensions.create('graphqlCodeGen', GraphQLCodeGenExtension)
8
9
project.tasks.register('generateGraphQL', JavaExec) {
10
group = 'code generation'
11
description = 'Generates GraphQL schema code'
12
13
classpath = project.sourceSets.main.runtimeClasspath
14
mainClass = extension.generatorClass.get()
15
16
inputs.files(project.fileTree(extension.schemaDir.get()))
17
outputs.dir(extension.outputDir.get())
18
}
19
20
project.tasks.named('compileJava') {
21
dependsOn('generateGraphQL')
22
}
23
}
24
}
25
26
class GraphQLCodeGenExtension {
27
final Property<String> generatorClass
28
final DirectoryProperty schemaDir
29
final DirectoryProperty outputDir
30
31
GraphQLCodeGenExtension(ObjectFactory objects) {
32
generatorClass = objects.property(String)
33
schemaDir = objects.directoryProperty()
34
outputDir = objects.directoryProperty()
35
}
36
}

Then use it in your build.gradle:

1
apply plugin: GraphQLCodeGenPlugin
2
3
graphqlCodeGen {
4
generatorClass = 'com.example.codegen.MyCodeGenerator'
5
schemaDir = file('src/main/resources/graphql')
6
outputDir = file('build/generated/graphql')
7
}

Build Optimization Tips

Incremental Builds

Gradle will skip code generation if:

  • The schema file hasn't changed
  • The output directory hasn't been deleted
  • The generator class hasn't changed

Use inputs and outputs declarations to enable this:

1
inputs.file('src/main/resources/schema.graphql')
2
inputs.file('src/main/java/com/example/codegen/MyCodeGenerator.java')
3
outputs.dir('build/generated/graphql')

Build Cache

Enable Gradle's build cache for faster builds across branches:

1
// gradle.properties
2
org.gradle.caching=true

Parallel Execution

If you have multiple independent schemas, generate them in parallel:

1
tasks.withType(JavaExec).configureEach {
2
if (name.startsWith('generate')) {
3
maxParallelForks = Runtime.runtime.availableProcessors()
4
}
5
}

Common Issues

Generated Code Not Found

Problem: Compiler can't find generated classes

Solution: Ensure generated directory is in sourceSets:

1
sourceSets {
2
main {
3
java {
4
srcDir 'build/generated/graphql'
5
}
6
}
7
}

Circular Dependency

Problem: generateGraphQL depends on compileJava depends on generateGraphQL

Solution: Your generator class should be in a separate source set or module:

1
// Option 1: Separate source set
2
sourceSets {
3
codegen {
4
java {
5
srcDir 'src/codegen/java'
6
}
7
}
8
}
9
10
tasks.register('generateGraphQL', JavaExec) {
11
classpath = sourceSets.codegen.runtimeClasspath
12
mainClass = 'com.example.codegen.MyCodeGenerator'
13
}

Code Generation Runs Too Often

Problem: Code generates every build even when schema hasn't changed

Solution: Add proper input/output declarations:

1
inputs.files(fileTree('src/main/resources/graphql'))
2
outputs.dir('build/generated/graphql')

IDE Integration

IntelliJ IDEA

IntelliJ automatically recognizes sourceSets configuration. After running code generation:

  1. Right-click the project → "Reload Gradle Project"
  2. Or: Gradle tool window → Reload button

Eclipse

Add generated sources to .classpath:

1
<classpathentry kind="src" path="build/generated/graphql"/>

VS Code

The Java extension will recognize sourceSets configuration automatically.

Best Practices

  1. Commit wrapper classes: Check in your *CodeGenerator.java files so the build is reproducible
  2. Don't commit generated code: Add build/generated/ to .gitignore
  3. Clean task integration: The provided example automatically cleans generated code
  4. Schema validation: Consider adding a schema linting task before generation
  5. Documentation generation: Generate GraphQL SDL documentation alongside code

Next Steps

Was this page helpful?

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.