Spring Boot Integration for Java SDKs
Speakeasy auto-generates Spring Boot starters
Configuration
Set generateSpringBootStarter: false in your gen.yaml to disable. Enabled by default.
Module Structure
build.gradle
Three modules provide complete Spring Boot integration:
- Auto-configuration: Bean registration with
@ConditionalOnMissingBean - Properties:
@ConfigurationPropertiesfrom OpenAPI spec - Starter: Dependency aggregator
Configuration Properties
Type-safe @ConfigurationProperties are auto-generated from your OpenAPI spec, namespaced under projectId:
@ConfigurationProperties(prefix = "my-api") // From your gen.yaml projectId public class MyApiProperties { // Core Configuration private String serverUrl; // From OpenAPI servers section private String server; // Server name (if using named servers) private int serverIdx = 0; // Server index (0-based, defaults to first server) // Server Variables (from OpenAPI spec) private ServerVariables serverVariables = new ServerVariables(); // Security Configuration (flattened from OpenAPI security schemes) private Security security = new Security(); // Global Parameters (from OpenAPI components) private Globals globals = new Globals(); // SDK Behavior Configuration private RetryConfig retryConfig = new RetryConfig(); private HttpClient httpClient = new HttpClient(); }Property Mapping:
- Servers: Indexed (
serverIdx) or named (server) with variables as enums - Security: Flattened schemes (API keys, OAuth, HTTP auth)
- Global Parameters: Headers, query params, path params from spec
- SDK Behavior: Retry policies, HTTP client settings
- Rich Types: OpenAPI enums → Java enums, duration strings →
Durationobjects
Auto-Configuration
Beans are conditionally registered based on classpath and properties:
@AutoConfiguration @ConditionalOnClass(SDK.class) @EnableConfigurationProperties(MyApiProperties.class) public class MyApiAutoConfiguration { @Bean @ConditionalOnMissingBean public SDK sdk(SDKConfiguration config) { return new SDK(config); // Main SDK bean } @Bean // Individual sub-SDKs automatically available @ConditionalOnMissingBean public UsersSDK usersSDK(SDK sdk) { return sdk.users(); } @Bean // Conditional on property presence @ConditionalOnProperty(prefix = "my-api.retry-config", name = "strategy") public RetryConfig retryConfig(MyApiProperties properties) { return convertToRetryConfig(properties.getRetryConfig()); } @Bean // Conditional on security configuration @ConditionalOnPropertyPrefix(prefix = "my-api.security") public SecuritySource securitySource(MyApiProperties properties) { return buildSecurityFromProperties(properties.getSecurity()); } }Bean Registration:
- Core SDK: Always present with starter
- Sub-SDKs: Per API group (Users, Orders, etc.)
- Security: Conditional on
my-api.security.* - Retry: Conditional on
my-api.retry-config.strategy - Async: When async mode enabled
Usage
Configure via application.yml:
my-api: # Namespace from your projectId server-url: "https://api.example.com" server-variables: # Rich type mapping with enum support environment: PROD # Enum values provide IDE dropdown selection region: US_EAST_1 # Type-safe enum prevents configuration errors security: # Structured security configuration api-key: "${API_KEY}" oauth: client-id: "${CLIENT_ID}" client-secret: "${CLIENT_SECRET}" retry-config: # SDK behaviors with readable duration formats strategy: BACKOFF # Enum with IDE autocomplete backoff: initial-interval: 500ms # Duration parsing: ms, s, m, h max-interval: 30s # Human-readable format max-elapsed-time: 5m # Automatically converted to Duration objects globals: # Global parameters from OpenAPI spec user-agent: "MyApp/1.0" api-version: "2023-10" http-client: # HTTP behavior configuration enable-debug-logging: false redacted-headers: ["Authorization", "X-API-Key"]Inject and use with zero boilerplate:
@RestController public class UserController { @Autowired private UsersSDK usersSDK; // Direct sub-SDK injection @Autowired private AsyncUsersSDK asyncUsersSDK; // Async variant // Synchronous usage @GetMapping("/users/{id}") public User getUser(@PathVariable String id) { return usersSDK.getUser() .userId(id) .call(); } // Reactive usage with WebFlux @GetMapping("/users/{id}/async") public Mono<User> getUserAsync(@PathVariable String id) { return Mono.fromFuture( asyncUsersSDK.getUser() .userId(id) .call() // Returns CompletableFuture<User> ); } // Streaming data @GetMapping(value = "/users/stream", produces = "application/x-ndjson") public Flux<User> streamUsers(@RequestParam String department) { Publisher<User> userStream = asyncUsersSDK.listUsers() .department(department) .callAsPublisher(); // Returns Publisher<User> for pagination return Flux.from(userStream); } }WebFlux Integration
Async SDKs integrate seamlessly with Spring WebFlux
CompletableFuture→MonoconversionPublisher→Fluxfor streaming (pagination, SSE, JSONL)- Non-blocking reactive streams
support
Publishing
No workflow changes required. Gradle auto-configures additional artifacts:
{project-name}-spring-boot-autoconfigure-{version}.jar{project-name}-spring-boot-starter-{version}.jar
Published alongside your main SDK to existing repositories.
Benefits
For API Producers:
- Zero deployment overhead
- Reduced support via familiar Spring Boot patterns
- Faster adoption by Spring developers
- Enterprise appeal with Actuator
and ecosystem compatibility
For SDK Users:
- Add starter dependency, configure via
application.yml - Type-safe properties with IDE support
- Rich type mapping (enums, durations)
- WebFlux integration when async enabled
Compatibility: Spring Boot 2.x/3.x, Java 11+
Last updated on