GraphQL Code Generator
This documentation covers the Brightspot GraphQL Code Generator for generating server-side Java code. This is NOT the same as GraphQL Codegen from The Guild, which generates client-side code. If you're looking to generate TypeScript/JavaScript client code, you want The Guild's tool instead. See our Best Practices guide for how to set it up.
The GraphQL Code Generator is a powerful tool that generates type-safe Java code from your GraphQL schema (SDL). It produces model classes, type generators, and scaffolding to accelerate GraphQL API development while maintaining type safety across your schema and implementation.
Why Use the Code Generator
- Type Safety: Generated Java classes match your GraphQL schema exactly, catching type mismatches at compile time
- Reduced Boilerplate: Automatically generates type generators, schema loaders, and model classes
- Maintainability: Schema changes immediately surface as compilation errors in implementations
- Documentation: Generated code includes javadoc from schema comments
- Productivity: Focus on business logic instead of repetitive schema mapping code
How It Works
- Define your schema in GraphQL SDL format
- Run the code generator via CLI or Gradle
- Extend the generated abstract classes with your business logic
- Expose your API through a GraphQL endpoint
The generator produces two kinds of output:
- Generated sources (regenerated on every run): an abstract schema context, a schema loader, abstract model classes for every type in your schema, type generator classes for schema registration, and sealing/utility support classes.
- Templated sources (scaffolded once, then yours to edit): an API endpoint class, and optionally a custom settings class.
Quick Start
Get started with a simple Hello World example:
Learn how to create your first GraphQL API with the code generator in just 5 steps.
Documentation
Core Guides
- Getting Started - Hello World tutorial without Gradle
- CLI Reference - All command-line options and Builder API
- Gradle Integration - Integrate into your build process
- Implementation Patterns - Best practices and patterns
- Troubleshooting - Common issues and solutions
Advanced Topics
- Advanced Examples - E-commerce, multi-schema, testing, and more
Features at a Glance
Type Mappings
Map GraphQL types directly to your existing domain models using the @javaType directive:
1type User @javaType(class: "com.example.domain.User") {2id: ID!3name: String!4email: String!5}
Custom Scalars
Map SDL scalars like UUID, Instant, and Long to the plugin's existing ScalarTypeGenerator implementations (or your own):
1new GraphQLCodeGenerator.Builder()2.addCustomScalar("UUID", UuidScalar.class)3.addCustomScalar("Instant", InstantScalar.class)4.build();
Sealed Models
Generated model classes are sealed: each model extends a generated sealing base class, so generated interfaces can't be implemented by arbitrary anonymous classes. Implementations must extend the generated abstract models—keeping schema changes flowing through your code as compile errors instead of silent drift.
Multiple APIs
Support for multiple independent GraphQL APIs in the same project with different prefixes and packages.
Example Schema to Code
Input Schema:
1type Query {2user(id: ID!): User3}45type User {6id: ID!7name: String!8}
Generated Code (with classNamePrefix("My"), abbreviated):
1public abstract class MySchemaContext implements SchemaContext {2public abstract MyQuery query();3}45public abstract class MyQuery extends MySealedClass {6public abstract MyUser user(String id);7}89public abstract class MyUser extends MySealedClass {10public abstract String id();11public abstract String name();12}
Your Implementation:
1public class MySchemaContextImpl extends MySchemaContext {2@Override3public MyQuery query() {4return new MyQuery() {5@Override6public MyUser user(String id) {7User domain = userService.findById(id);8return domain != null ? toUser(domain) : null;9}10};11}1213private MyUser toUser(User domain) {14return new MyUser() {15@Override16public String id() {17return domain.getId();18}1920@Override21public String name() {22return domain.getName();23}24};25}26}
With a type mapping (@javaType or addTypeMapping), the generated signatures use your domain class directly and the context declares the toUser converter for you—see Implementation Patterns.
Integration Options
Standalone (No Build Tool)
Run the generator's main class directly:
1java -cp "lib/*" com.psddev.graphql.schema.codegen.GraphQLCodeGenerator \2--sdl schema.graphql \3--package com.example.generated \4--generated-sources-dir build/generated
Gradle
Integrate into your build:
1tasks.register('generateGraphQL', JavaExec) {2classpath = sourceSets.main.runtimeClasspath3mainClass = 'com.example.MyCodeGenerator'4}56tasks.named('compileJava') {7dependsOn('generateGraphQL')8}
Maven
Use exec-maven-plugin:
1<plugin>2<groupId>org.codehaus.mojo</groupId>3<artifactId>exec-maven-plugin</artifactId>4<executions>5<execution>6<phase>generate-sources</phase>7<goals>8<goal>java</goal>9</goals>10</execution>11</executions>12<configuration>13<mainClass>com.example.MyCodeGenerator</mainClass>14</configuration>15</plugin>
Community & Support
- Check the Troubleshooting Guide for common issues
- See Advanced Examples for complex scenarios
- Review Implementation Patterns for best practices
Next Steps
- Start with the basics: Getting Started Guide
- Automate your workflow: Gradle Integration
- Learn best practices: Implementation Patterns
- Explore advanced features: Advanced Examples