Router builder gutter shows the inner route path without its path()/nest() prefix

Closed
#609 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
java, kotlin, spring
Domain
api, devtools

Research direction

Start in modules/spring-web/src/main/kotlin/com/explyt/spring/web/providers/RouterEndpointActionsLineMarkerProvider.kt, at getPathFromRouteFunction, which reads only the verb call's first argument and ignores enclosing path() or nest() calls. Then read RouterBuilderRouteWalker.kt to see how it composes prefixes for the endpoint list. Done when the gutter on a nested GET shows the full composed path, matching the endpoint list, for both servlet and reactive builders.

Written by the indexing model from the issue text.

Description

in:spring-web

Summary

In a Java RouterFunctions.route() builder, the endpoint gutter on a route declared inside a path() or nest() callback shows only the route's own URI. It drops the enclosing prefix. After #580, the endpoint model (Endpoints tool window, endpoint search, Spring MCP endpoint tools) reports the composed path, so the gutter and the endpoint list disagree.

Reproduction

@Configuration
public class RouterConfig {
    @Bean
    public RouterFunction<ServerResponse> routes(Handler h) {
        return RouterFunctions.route()
                .path("/a", b -> b.GET("/b", h::list))
                .build();
    }
}
  • Endpoint list: GET /a/b
  • Gutter on GET (Run / HTTP request actions): /b

The same applies to nest(RequestPredicates.path("/a"), b -> b.GET("/b", …)), to the Supplier forms, and to nested path() calls (/a/b/c shown as /c). Both the servlet and the reactive stack are affected.

Cause

RouterEndpointActionsLineMarkerProvider (modules/spring-web/src/main/kotlin/com/explyt/spring/web/providers/RouterEndpointActionsLineMarkerProvider.kt):

  • getLineMarkerFor (:44–90) installs the marker on any identifier named like a route verb inside a @Bean method. It takes the path from getPathFromRouteFunction(uMethodCall) (:60).
  • getPathFromRouteFunction (:99–111) visits only the verb call expression itself and reads its first argument. It never looks at the enclosing path()/nest() calls, so the prefix is lost.

Suggested fix

Reuse RouterBuilderRouteWalker (modules/spring-web/src/main/kotlin/com/explyt/spring/web/loader/RouterBuilderRouteWalker.kt, added in #580). It already walks the builder chain and its callbacks, and it composes prefixes from path(String, …), RequestPredicates.path(..) and and(..). Have it also return the verb call each BuilderRoute comes from. The gutter could then pick the route whose call is the gutter element, instead of re-reading the URI argument.

This brings two more fixes:

  • Routes under an undecidable nest predicate (a variable, a helper method, or, negate) would get no gutter path instead of a wrong one, consistent with the endpoint list.
  • A URI-less verb overload is handled the same way in both places.

Scope

spring-web, Java builder routes only. The Kotlin router DSL gutter is separate; see #576 and #606.

Dominant language
Kotlin
Stars
163
Forks
16
Avg merge
6h 5m
Merged PRs (30d)
180

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from explyt/spring-plugin

All issues in explyt/spring-plugin

Similar issues

More Kotlin issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.