Skip to content

Conversation

@JKaplanEmpty-Nes
Copy link

The current WebFlux API resolution returned a nullable String, this prevented custom API resolvers to be based on values which would need to be blocked.
For example, creating an API version resolver based on the Authorized Principal. Since this is returned as a Mono in a server exchange.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 30, 2025
@JKaplanEmpty-Nes JKaplanEmpty-Nes force-pushed the main branch 4 times, most recently from 7a312d0 to 396a634 Compare December 30, 2025 18:18
@JKaplanEmpty-Nes JKaplanEmpty-Nes changed the title Change the API version resolution from being a nullable String to a Mono String Change the WebFlux API version resolution from being a nullable String to a Mono String Dec 30, 2025
@bclozel
Copy link
Member

bclozel commented Dec 30, 2025

It is unfortunately too late for this type of change. This would break existing public contracts in a spectacular fashion. I will leave this open for now so we can discuss the use case.

@bclozel bclozel added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Dec 30, 2025
@JKaplanEmpty-Nes
Copy link
Author

It is unfortunately too late for this type of change. This would break existing public contracts in a spectacular fashion. I will leave this open for now so we can discuss the use case.

What if I changed the public contracts so that the old return was there, but added a new reactive one and by default it would enclose the old result in a mono?

@bclozel
Copy link
Member

bclozel commented Dec 30, 2025

We can always consider solutions like that. Let us discuss this matter first.

@JKaplanEmpty-Nes JKaplanEmpty-Nes force-pushed the main branch 2 times, most recently from 1a29790 to 40f7f4c Compare December 30, 2025 19:57
@JKaplanEmpty-Nes
Copy link
Author

JKaplanEmpty-Nes commented Dec 30, 2025

We can always consider solutions like that. Let us discuss this matter first.

Absolutely I would love to discuss my use case, just in case I made the change to not break the previous contracts.

The specific case is that we set the version (alpha, beta, GA) based on the Authorized Principal of the request.
However using WebFlux we get that wrapped in a Mono, which we obviously can't block to resolve.

Copy link
Contributor

@rstoyanchev rstoyanchev left a comment

Choose a reason for hiding this comment

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

This was unfortunately an oversight, but we need to consider the best way to get there with the least disruption.

I do like the idea of allowing an ApiVersionResolver to be sync or async, so the resolveVersionReactively method with a default implementation is good, but I would call it resolveVersionAsync.

However, it doesn't make sense to keep both sync and async variants at the level of ApiVersionStrategy, so we should deprecate the sync version for removal, and again call the new method resolveVersionAsync. A similar pattern for resolveParseAndValidate.

During the deprecation phase, we do need to continue to call the sync resolveParseAndValidate first, suppressing any MissingApiVersionException, and then conditionally call the new async variant if the sync version did not produce a version.

Let me know if you plan to make those updates.

@rstoyanchev rstoyanchev self-assigned this Jan 5, 2026
@rstoyanchev rstoyanchev added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 5, 2026
@rstoyanchev rstoyanchev added this to the 7.0.3 milestone Jan 5, 2026
@rstoyanchev rstoyanchev changed the title Change the WebFlux API version resolution from being a nullable String to a Mono String Allow WebFlux ApiVersionResolver to return a Mono Jan 5, 2026
@JKaplanEmpty-Nes JKaplanEmpty-Nes force-pushed the main branch 3 times, most recently from 1947510 to e0776f9 Compare January 5, 2026 18:25
@JKaplanEmpty-Nes
Copy link
Author

JKaplanEmpty-Nes commented Jan 5, 2026

I pushed the following changes:
ApiVersionResolver.resolveVersionReactively renamed to resolveVersionAsync
ApiVersionStrategy.resolveVersionReactively renamed to resolveVersionAsync

Deprecated ApiVersionStrategy.resolveVersion since 7.0.3

Instead of defaulting the async resolver to sync resolver in the ApiVersionStrategy, both methods are being called when calling resolveParseAndValidate. If the sync method throws a MissingApiVersionException then it is suppressed.

@rstoyanchev
Copy link
Contributor

@JKaplanEmpty-Nes, thinking further about the use case:

The specific case is that we set the version (alpha, beta, GA) based on the Authorized Principal of the request.

Could you clarify why the version depends on the logged in user? It seems to me the version to use should match the one requested by the client, which knows best what their capability and compatibility level is.

@JKaplanEmpty-Nes
Copy link
Author

@JKaplanEmpty-Nes, thinking further about the use case:

The specific case is that we set the version (alpha, beta, GA) based on the Authorized Principal of the request.

Could you clarify why the version depends on the logged in user? It seems to me the version to use should match the one requested by the client, which knows best what their capability and compatibility level is.

Sure, I can go into a bit more detail. My use case is very specific, but allowing async API version resolution will solve for it and other possible cases.

We use a 3rd party service called LaunchDarkly. It allows us to select the correct version of an API based on a supplied context. I created a Launch Darkly API Version resolver for WebMvc just fine however I was unable to do it for WebFlux. The context we send to Launch Darkly includes information from the JWT.

This allows us to switch versions for specific segments of users and allows us to change the routing at any time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants