Skip to content

Fixed search resource routing when repository name is longer than 'search' keyword - #2600

Open
ruthst00 wants to merge 2 commits into
spring-projects:mainfrom
ruthst00:DATAREST-1495-ruthes00
Open

Fixed search resource routing when repository name is longer than 'search' keyword#2600
ruthst00 wants to merge 2 commits into
spring-projects:mainfrom
ruthst00:DATAREST-1495-ruthes00

Conversation

@ruthst00

@ruthst00 ruthst00 commented Sep 9, 2026

Copy link
Copy Markdown

Fixes #1853

Root Cause: GET /authors/search returned 400 BAD_REQUEST due to Spring MVC's AntPatternComparator using string length as a tiebreaker. For a repository named "authors" (7 chars), the item-resource pattern /authors/{id} scored length 10 while the search pattern /{repository}/search scored length 9, causing the wrong handler to win. "search" was then incorrectly treated as an entity ID, producing a 400 error.

Fix: Overrode getMappingComparator() in RepositoryRestHandlerMapping to wrap the default Spring MVC comparator with a SDR-specific tiebreaker. The tiebreaker (compareByLastSegmentLiteralness) checks whether the last path segment of each matched pattern is a literal (e.g., /search) or a variable (e.g., /{id}). Patterns with a literal last segment are always ranked higher, ensuring /{repository}/search always beats /{repository}/{id} or /authors/{id} regardless of string length.

Files changed (3):

  • RepositoryRestHandlerMapping.java — Added getMappingComparator() override with compareByLastSegmentLiteralness() and isLastSegmentLiteral() helpers; added @author Steve Rutherford
  • RepositoryRestHandlerMappingUnitTests.java — Added 3 unit tests (handler resolution, isLastSegmentLiteral true/false cases); added @author Steve Rutherford
  • JpaWebTests.java — Added integration test verifying GET /authors/search routes to the search handler (returns 404 "no searches exposed" instead of 400 "bad request"); added @author Steve Rutherford

  • You have read the Spring Data contribution guidelines.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

…ame is longer than 'search' keyword.

Override getMappingComparator in RepositoryRestHandlerMapping to add a
tiebreaker that prefers patterns whose last path segment is a literal
(e.g. /{repository}/search) over patterns whose last segment is a path
variable (e.g. /{repository}/{id} or /authors/{id}).

Previously, AntPatternComparator's length-based heuristic caused
GET /authors/search to be routed to the item-resource handler
(/authors/{id}, effective length 10) instead of the search-resource
handler (/{repository}/search, effective length 9), because the literal
repository name 'authors' (7 chars) made the item-resource pattern
longer than the search pattern. This resulted in a 400 BAD_REQUEST
response when 'search' could not be bound as an entity ID.

The fix introduces isLastSegmentLiteral() and compareByLastSegmentLiteralness()
helpers, and wraps the default Spring MVC comparator so that literal
last-segment patterns always beat variable last-segment patterns before
the length-based comparison is applied.

Signed-off-by: ruthes00 <ruthes00@gmail.com>
…header.

Signed-off-by: ruthes00 <ruthes00@gmail.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 9, 2026
@ruthst00 ruthst00 changed the title DATAREST-1495-ruthes00: Fix search resource routing when repository name is longer than 'search' keyword Fixed search resource routing when repository name is longer than 'search' keyword Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When multiple matches are found in lookupHandlerMethod, comparison by PatternsRequestCondition leads to strange results. [DATAREST-1495]

2 participants