Skip to content

feat(kotlin-spring): add suspendFunctions option for coroutine support - #23444

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
thejeff77:feat/suspend-functions-option
May 19, 2026
Merged

wing328 merged 1 commit into
OpenAPITools:masterfrom
thejeff77:feat/suspend-functions-option

Conversation

@thejeff77

@thejeff77 thejeff77 commented Apr 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds a new suspendFunctions boolean config option (default: false) to the kotlin-spring generator
  • When enabled, all generated API operations get the suspend keyword on controller interfaces, delegate interfaces, service interfaces, and standalone controllers
  • Enables Spring MVC + Kotlin coroutines without requiring the full reactive stack (WebFlux/Flow), eliminating the need for runBlocking in delegate implementations

Changes

  • KotlinSpringServerCodegen.java: Added constant, field, CLI switch, and processOpts() handling
  • api.mustache, apiDelegate.mustache, apiInterface.mustache, service.mustache: Added suspend keyword when suspendFunctions=true, falling back to existing reactive logic when false
  • KotlinSpringServerCodegenTest.java: 3 new tests (interface-only, delegate pattern, defaults-to-false)
  • docs/generators/kotlin-spring.md: Documented new option

Usage

configOptions:
  delegatePattern: "true"
  suspendFunctions: "true"

Test plan

  • suspendFunctionsInterfaceOnly — verifies suspend fun in interface-only mode
  • suspendFunctionsWithDelegatePattern — verifies suspend fun in both API interface and delegate
  • suspendFunctionsDefaultsToFalse — verifies no suspend when option not set
  • Existing reactive tests pass (no regressions)

🤖 Generated with Claude Code


Summary by cubic

Adds a new suspendFunctions option to the kotlin-spring generator to emit suspend for all API operations, enabling Kotlin coroutines with Spring MVC without WebFlux. Default is false; no changes unless enabled, removing the need for runBlocking in delegates and services.

  • New Features

    • New suspendFunctions switch (default: false) in KotlinSpringServerCodegen; exposed via CLI addSwitch, persisted via processOpts, configurable via additionalProperties/configOptions.
    • Templates (api.mustache, apiInterface.mustache, apiDelegate.mustache, service.mustache) add suspend when enabled; otherwise use existing reactive logic. Works with delegatePattern, serviceInterface, and interface-only. Docs updated (option added to table).
  • Bug Fixes

    • Tests read files with StandardCharsets.UTF_8 to satisfy the forbiddenapis plugin.

Written for commit a8ab0af. Summary will update on new commits. Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 7 files

@thejeff77

Copy link
Copy Markdown
Contributor Author

Requesting Review

Tagging the Kotlin technical committee and recent active contributors to the kotlin-spring generator for visibility:

Kotlin TC: @karismann @Zomzog @4brunu @yutaka0m @stefankoppier @e5l @dennisameling

Recent active contributors to kotlin-spring: @metlicka @wing328 @neeme-praks-sympower @takkiraz

This PR adds a suspendFunctions config option (default: false) that generates suspend fun for all API operations without requiring the full reactive stack. It's useful for Spring MVC + Kotlin coroutines — the current workaround is wrapping delegate calls in runBlocking, which this eliminates.

The change is minimal (8 lines in the codegen class, 1 line per template × 4 templates) and backward-compatible.

@thejeff77

Copy link
Copy Markdown
Contributor Author

Friendly bump! 👋 Would love to get some eyes on this when anyone has a chance.

Kotlin TC: @karismann @Zomzog @4brunu @yutaka0m @stefankoppier @e5l @dennisameling
Recent kotlin-spring contributors: @metlicka @wing328

Happy to address any feedback. Thanks!

@thejeff77

Copy link
Copy Markdown
Contributor Author

Re: the failing ci/circleci: node0 check — this is unrelated to this PR. The failure is in the openapi-generator-gradle-plugin Maven wrapper build:

Plugin org.fortasoft:gradle-maven-plugin:1.0.8 or one of its dependencies could not be resolved

All actual openapi-generator modules (core library, executable, maven-plugin) built and tested successfully. The other 3 CircleCI nodes pass, and all GitHub Actions checks are green.

@wing328

wing328 commented May 18, 2026

Copy link
Copy Markdown
Member

@thejeff77 thanks for the PR

can you please resolve the merge conflicts when you've time?

Then please PM me via Slack to have this reviewed and merged

https://join.slack.com/t/openapi-generator/shared_invite/zt-36ucx4ybl-jYrN6euoYn6zxXNZdldoZA

Add a new `suspendFunctions` boolean config option (default: false) to
the kotlin-spring generator. When enabled, all generated API operations
get the `suspend` keyword on controller interfaces, delegate interfaces,
service interfaces, and standalone controllers.

This enables Spring MVC + Kotlin coroutines without requiring the full
reactive stack (WebFlux/Flow). Users no longer need `runBlocking` in
their delegate implementations.

Includes tests for interface-only, delegate pattern, default-disabled,
and service-interface variants. Uses StandardCharsets.UTF_8 explicitly
to satisfy the forbiddenapis plugin.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@thejeff77
thejeff77 force-pushed the feat/suspend-functions-option branch from 3055e0a to a8ab0af Compare May 19, 2026 16:05
@wing328

wing328 commented May 19, 2026

Copy link
Copy Markdown
Member

Ran some tests locally and the result is good.

Thanks for the contribution.

@wing328
wing328 merged commit 29031ca into OpenAPITools:master May 19, 2026
14 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants