Feature 9: Code Generation Infrastructure
Purpose: This guide provides step-by-step instructions for setting up OpenAPI Generator foundational infrastructure.
Dependencies:
- Requires Code Quality & Developer Experience to be completed first (for checkstyle suppressions file to exclude generated code)
Related Documents:
- Boilerplate Enhancements Solution Architecture - System design overview
- Boilerplate Enhancements Epic - Capability definition
Overview
What This Guide Covers
Code Generation Infrastructure provides general-purpose code generation setup for future APIs:
- OpenAPI Generator Gradle plugin configuration
- Basic setup (generalized, not AI-specific)
- Test with toy OpenAPI spec
- Generated code exclusion from checkstyle
What's Included:
- OpenAPI Generator plugin configuration
- SourceSets configuration for generated sources
- Toy OpenAPI spec file for testing
- Build integration
What's NOT Included:
- ❌ AI-specific OpenAPI spec (Text Intelligence Epic)
- ❌ AI-specific generated code (Text Intelligence Epic)
- ❌ AI controller implementation (Text Intelligence Epic)
Note: This guide sets up the foundational infrastructure. AI-specific usage (spec file, generated packages, controller implementation) belongs in the Text Intelligence Epic.
Prerequisites
- Springular boilerplate setup
- Understanding of Gradle build configuration
- Basic understanding of OpenAPI specifications
- Checkstyle suppressions file configured (from Code Quality guide)
Implementation Steps
Step 1: Add OpenAPI Generator Plugin
File: server/build.gradle
Purpose: Add OpenAPI Generator Gradle plugin for code generation.
Find plugins block and add:
plugins {
// ... existing plugins ...
id 'org.openapi.generator' version '7.2.0'
}
Complete plugins block example:
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
id 'checkstyle'
id 'org.openapi.generator' version '7.2.0'
}
Why Version 7.2.0:
- Proven version from POC
- Stable and well-tested
- Supports Spring Boot 3
Step 2: Configure OpenAPI Generator Task
File: server/build.gradle
Purpose: Configure OpenAPI Generator task with basic setup (generalized, not AI-specific).
Key Points:
- ✅ Uses toy OpenAPI spec for testing
- ✅ Generalized package names (not AI-specific)
- ✅ Spring Boot 3 compatible
- ✅ Interface-only generation
Add configuration (after dependencies block or in appropriate section):
openApiGenerate {
generatorName = 'spring'
inputSpec = "$projectDir/src/main/resources/api/toy-api-openapi.yml".toString()
outputDir = "$buildDir/generated-sources/openapi".toString()
apiPackage = 'com.saas.springular.common.api.generated'
modelPackage = 'com.saas.springular.common.api.generated.model'
configOptions = [
dateLibrary: 'java8',
serializationLibrary: 'jackson',
useSpringBoot3: 'true',
hideGenerationTimestamp: 'true',
openApiNullable: 'false',
interfaceOnly: 'true',
useTags: 'true'
]
}
Configuration Explanation:
generatorName = 'spring'- Uses Spring generator (creates interfaces, not controllers)inputSpec- Path to OpenAPI spec file (toy spec for testing)outputDir- Output directory for generated codeapiPackage- Package for generated API interfacesmodelPackage- Package for generated model classesdateLibrary: 'java8'- Uses Java 8 date/time typesserializationLibrary: 'jackson'- Uses Jackson for JSONuseSpringBoot3: 'true'- Spring Boot 3 compatiblehideGenerationTimestamp: 'true'- Removes timestamp from generated codeopenApiNullable: 'false'- No nullable annotations (simpler code)interfaceOnly: 'true'- Generates interfaces only (no controller implementation)useTags: 'true'- Uses OpenAPI tags for organization
Step 3: Configure SourceSets for Generated Sources
File: server/build.gradle
Purpose: Add generated sources directory to SourceSets.
Find or create sourceSets block and add:
sourceSets {
main {
java {
srcDirs += ['build/generated-sources/openapi/src/main/java']
}
}
}
Complete sourceSets configuration (if checkstyle configuration exists, merge with it):
sourceSets {
main {
java {
srcDirs = ['src/main/java']
srcDirs += ['build/generated-sources/openapi/src/main/java']
exclude '**/generated/**' // For checkstyle (exclude path patterns, not generated-sources dir)
}
}
}
Note: The exclude '**/generated/**' is for checkstyle exclusion patterns, not for SourceSets. The generated-sources directory should be included in SourceSets for compilation.
Step 4: Configure Build Dependency
File: server/build.gradle
Purpose: Ensure OpenAPI generation runs before compilation.
Add dependency (at the end of build.gradle or in appropriate section):
compileJava.dependsOn tasks.openApiGenerate
Why This Dependency:
- Ensures generated code exists before compilation
- Automatic generation on build
- No manual generation step needed
Step 5: Configure Clean Task
File: server/build.gradle
Purpose: Clean generated sources on clean task.
Find clean block or create it:
clean {
delete 'build/generated-sources'
}
Complete clean configuration:
tasks.named('clean') {
delete 'build/generated-sources'
}
Why Clean Configuration:
- Removes generated code on clean
- Ensures fresh generation on next build
- Prevents stale generated code
Step 6: Create Toy OpenAPI Spec File
File: server/src/main/resources/api/toy-api-openapi.yml
Purpose: Create a simple OpenAPI spec for testing the infrastructure.
Key Points:
- ✅ Simple hello-world API
- ✅ Not AI-specific
- ✅ Tests infrastructure works
- ✅ Can be replaced with actual specs later
Create file:
openapi: 3.0.3
info:
title: Toy API
version: 1.0.0
description: Simple toy API for testing OpenAPI Generator infrastructure
servers:
- url: http://localhost:8080/api
description: Local development server
paths:
/hello:
get:
tags:
- hello
summary: Hello endpoint
operationId: hello
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/HelloResponse'
components:
schemas:
HelloResponse:
type: object
properties:
message:
type: string
example: "Hello, World!"
required:
- message
Why Toy Spec:
- Tests infrastructure without AI dependencies
- Simple and easy to understand
- Proves infrastructure works
- Can be replaced/removed when actual specs are added
Verification
Step 1: Verify Code Generation Works
Run build:
./gradlew clean build
Expected Result:
- OpenAPI Generator task runs
- Code generated in
build/generated-sources/openapi/src/main/java - Generated code compiles successfully
- Build completes successfully
Check Generated Code:
ls -la server/build/generated-sources/openapi/src/main/java/com/saas/springular/common/api/generated/
Expected Files:
HelloApi.java(interface)model/HelloResponse.java(model class)
Step 2: Verify Generated Code Compiles
Check compilation:
./gradlew compileJava
Expected Result:
- Compilation succeeds
- No errors related to generated code
- Generated classes are available
Step 3: Verify Checkstyle Excludes Generated Code
Run checkstyle (after Code Quality guide is complete):
./gradlew checkstyleMain
Expected Result:
- Checkstyle runs successfully
- Generated code is excluded (no checkstyle errors from generated code)
- Source code is still checked
Verify Suppressions:
- Check
config/checkstyle/checkstyle-suppressions.xmlincludes generated sources patterns - Generated code should not appear in checkstyle reports
Step 4: Verify Clean Task Works
Run clean:
./gradlew clean
Expected Result:
- Generated sources directory is deleted
build/generated-sourcesshould not exist after clean
Verify:
ls -la server/build/generated-sources/ # Should not exist or be empty
Testing
Unit Tests
No unit tests required (infrastructure setup).
Integration Tests
Verify build integration:
- Build succeeds with OpenAPI generation
- Generated code compiles
- Clean removes generated code
- Rebuild regenerates code
Verify checkstyle integration:
- Generated code excluded from checkstyle
- Source code still checked
- Checkstyle passes with clean source code
Troubleshooting
Generated Code Not Found
Issue: Compilation fails with "package not found" errors.
Solution:
- Verify
sourceSetsconfiguration includes generated sources directory - Check
compileJava.dependsOn tasks.openApiGenerateis set - Run
./gradlew clean buildto regenerate - Verify output directory path is correct
Checkstyle Fails on Generated Code
Issue: Checkstyle reports errors from generated code.
Solution:
- Verify
checkstyle-suppressions.xmlexists - Check suppressions file includes generated sources patterns
- Verify suppressions file path in build.gradle
- Check generated code paths match suppressions patterns
OpenAPI Generator Task Not Running
Issue: Generated code doesn't exist after build.
Solution:
- Verify plugin is in
pluginsblock - Check
compileJava.dependsOn tasks.openApiGenerateis set - Run
./gradlew openApiGeneratemanually to test - Check OpenAPI spec file exists and is valid
Usage Pattern for Future APIs
When adding a new OpenAPI spec:
-
Create spec file:
- Place in
src/main/resources/api/ - Use descriptive name (e.g.,
user-service-openapi.yml)
- Place in
-
Update build.gradle:
- Change
inputSpecto new spec file path - Optionally update
apiPackageandmodelPackagefor organization - Or create separate
openApiGeneratetasks for multiple specs
- Change
-
Build:
./gradlew clean build -
Implement generated interfaces:
- Create controller implementing generated interface
- Add business logic
- Wire to service layer
Example: Multiple Specs (advanced):
tasks.register('openApiGenerateUserService', org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
generatorName = 'spring'
inputSpec = "$projectDir/src/main/resources/api/user-service-openapi.yml".toString()
outputDir = "$buildDir/generated-sources/openapi-user".toString()
apiPackage = 'com.saas.springular.common.api.user.generated'
modelPackage = 'com.saas.springular.common.api.user.generated.model'
// ... configOptions ...
}
compileJava.dependsOn tasks.openApiGenerateUserService
Next Steps
After completing this guide:
- ✅ Test Infrastructure - Test profile configuration
For Text Intelligence Epic:
- This infrastructure will be used to generate AI service API interfaces
- AI-specific spec file and generated code will be added in Text Intelligence implementation guides
Summary
This implementation provides:
- ✅ Code Generation Infrastructure: OpenAPI Generator plugin configured
- ✅ Generalized Setup: Not AI-specific, usable for any API
- ✅ Build Integration: Automatic generation on build
- ✅ Checkstyle Exclusion: Generated code excluded from code quality checks
- ✅ Testing: Toy spec proves infrastructure works
- ✅ Documentation: Pattern documented for future use
All changes provide foundational infrastructure for code generation. AI-specific usage will be added in the Text Intelligence Epic.