Skip to content

Support mapping every controller as a REST resource - #16273

Open
codeconsole wants to merge 2 commits into
apache:8.0.xfrom
codeconsole:feat/wildcard-resources-mapping
Open

Support mapping every controller as a REST resource#16273
codeconsole wants to merge 2 commits into
apache:8.0.xfrom
codeconsole:feat/wildcard-resources-mapping

Conversation

@codeconsole

Copy link
Copy Markdown
Contributor

An application whose controllers all follow the RESTful resource conventions has to declare a resources mapping per controller, or hand-write the eight equivalent method-prefixed mappings. The first grows the mapping table with the controller count; the second copies a framework convention into application code, where it drifts when the convention changes.

Passing * as the resources argument applies the conventions to every controller:

"/$controller"(resources: '*')

That generates the eight mappings once — not once per controller — and resolves the controller from the URL when a request is matched:

get    "/$controller(.$format)?"(action: 'index')
post   "/$controller(.$format)?"(action: 'save')
get    "/$controller/create"(action: 'create')
get    "/$controller/$id/edit"(action: 'edit')
get    "/$controller/$id(.$format)?"(action: 'show')
put    "/$controller/$id(.$format)?"(action: 'update')
patch  "/$controller/$id(.$format)?"(action: 'patch')
delete "/$controller/$id(.$format)?"(action: 'delete')

includes, excludes and group prefixes compose as they do for a named resource:

group "/api/v1", {
    "/$controller"(resources: '*', excludes: ['create', 'edit'])
}

The captured controller and action are validated as they are for any other wildcard mapping, so a URI that does not correspond to a registered controller and action does not match.

Limitations, both rejected when the mappings are evaluated rather than left to produce mappings that cannot match:

  • the URL must capture the controller, so "/books"(resources: '*') is an error
  • child resources cannot be nested within the mapping, since the parent controller is not known until a request is matched

An application whose controllers all follow the RESTful resource
conventions had to declare a resources mapping per controller, or
hand-write the eight equivalent method-prefixed mappings. The first
grows the mapping table with the controller count; the second copies a
framework convention into application code, where it drifts when the
convention changes.

Passing '*' as the resources argument now generates the eight mappings
once and leaves the controller to be resolved from the URL's own capture
when a request is matched, which the existing runtime constraint
evaluator already supports. includes, excludes and group prefixes
compose as they do for a named resource.

Because the controller is not known until a request is matched, two
cases are rejected when the mappings are evaluated rather than left to
produce mappings that cannot match: a URL that does not capture the
controller, and a nested child resource, which would otherwise build a
constraint named "nullId".
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.7043%. Comparing base (4309d5b) to head (6af0bf5).

Files with missing lines Patch % Lines
...grails/web/mapping/DefaultUrlMappingEvaluator.java 80.0000% 1 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##                8.0.x     #16273        +/-   ##
==================================================
- Coverage     54.7149%   54.7043%   -0.0106%     
+ Complexity      20421      20419         -2     
==================================================
  Files            2101       2101                
  Lines          100978     100992        +14     
  Branches        17907      17913         +6     
==================================================
- Hits            55250      55247         -3     
- Misses          37860      37878        +18     
+ Partials         7868       7867         -1     
Files with missing lines Coverage Δ
...grails/web/mapping/DefaultUrlMappingEvaluator.java 78.3557% <80.0000%> (+0.0052%) ⬆️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@testlens-app

testlens-app Bot commented Aug 30, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

⚠️ TestLens detected flakiness ⚠️

Test Summary

Groovy Snapshot Canary Build / Build Grails (shard 1) > :grails-test-examples-gsp-sitemesh3:integrationTest

Test Runs Flakiness
EndToEndSpec > async multiple levels of layouts ❌ ✅ 1% 🟡

🏷️ Commit: 6af0bf5
▶️ Tests: 56415 executed
⚪️ Checks: 89/89 completed


Learn more about TestLens at testlens.app/docs.

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant