🔥 feat: Add URL() method to Route for generating URLs with parameters#4195
🔥 feat: Add URL() method to Route for generating URLs with parameters#4195
Conversation
This implements the feature requested in the issue to allow generating URLs from
named routes with parameter substitution. Users can now do:
route := app.GetRoute("a-name")
url, err := route.URL(Map{"name": "name-val"})
// Returns: "/a/name-val"
The implementation:
- Added Route.URL() method that generates URLs by filling in route parameters
- Uses case-insensitive parameter matching (matching Fiber's default behavior)
- Supports all parameter types: named params, wildcards, and greedy params
- Added comprehensive test coverage with 11 test cases
- All quality checks pass (format, lint, test)
Agent-Logs-Url: https://github.com/gofiber/fiber/sessions/7256ea7c-dddf-4096-bb79-2fa6c3eefe39
Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4195 +/- ##
==========================================
+ Coverage 91.16% 91.21% +0.04%
==========================================
Files 123 123
Lines 11855 11885 +30
==========================================
+ Hits 10808 10841 +33
+ Misses 659 657 -2
+ Partials 388 387 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds a new Route.URL(params Map) (string, error) API to generate relative URLs from a route’s parsed path segments by substituting route parameters, aligning with existing named-route URL generation patterns in the codebase.
Changes:
- Introduces
(*Route).URL()to build URLs fromrouteParsersegments with parameter substitution (including wildcards/greedy params). - Adds unit tests for
Route.URL()covering common parameter and wildcard cases. - Updates generated
Ctx/Resinterface docs forEnd()with a streaming-related note.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| router.go | Adds Route.URL() implementation using routeParser segments and bytebuffer pooling. |
| router_test.go | Adds Test_Route_URL subtests for parameter substitution behavior. |
| res_interface_gen.go | Updates generated Res interface docs for End(). |
| ctx_interface_gen.go | Updates generated Ctx interface docs for End(). |
|
@copilot apply changes based on the comments in this thread |
…ase sensitivity, revert generated files Agent-Logs-Url: https://github.com/gofiber/fiber/sessions/b7a53bed-4d39-487b-8e01-9ecfe5d38b64 Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
Applied all review feedback in commit 26faa1d:
|
|
@copilot apply changes based on the comments in this thread |
…e caseSensitive Agent-Logs-Url: https://github.com/gofiber/fiber/sessions/234974ca-1106-44ec-9ea0-af2206caff3f Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
Applied all three review comments in commit 6b37d8d:
Also added a |
|
@copilot Your latest changes broke unit tests. |
I investigated this before making any speculative changes. The exact workflow-style unit run ( |
|
@ReneWerner87 let me run copilot once more here before merging |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the URL method to the Route struct, enabling the generation of relative URLs from named routes with support for parameter substitution, including named, wildcard, and plus segments. The implementation refactors existing logic into a shared buildRouteURL helper and respects the application's case-sensitivity configuration. Feedback identifies a logic bug in the case-insensitive parameter matching that leads to non-deterministic results and suggests simplifying redundant variable declarations.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
@copilot There's a bug in the case-insensitive parameter matching logic. The To fix this, you should use a local boolean flag within this block to track if a match has been found. // Fall back to a case-insensitive match using a deterministic winner
var matchedKey string
foundMatch := false
for key := range params {
if utils.EqualFold(key, segment.ParamName) && (!foundMatch || key < matchedKey) {
matchedKey = key
foundMatch = true
}
}
if foundMatch {
val = params[matchedKey]
found = true
} |
Agent-Logs-Url: https://github.com/gofiber/fiber/sessions/6b2ae8da-f708-42b5-9e9b-7e3795de0ec5 Co-authored-by: gaby <835733+gaby@users.noreply.github.com>
Fixed in 77044e2. I updated the case-insensitive fallback to use a local |
Description
Adds a new
Route.URL(params Map) (string, error)API for generating relative URLs directly from named routes with parameter substitution.This change lets users construct URLs programmatically from
app.GetRoute(name)without going throughCtx.GetRouteURL(), while keeping behavior aligned with existing named-route URL generation. Follow-up review feedback refined the implementation so URL generation is deterministic, respects route-level case sensitivity, handles mounted sub-app routes correctly, prefers the matching greedy token type for+vs*, gracefully falls back toroute.Pathwhen a route has no parsed segments, avoids per-call allocations in greedy fallback lookup by using precomputed string key orders, and uses a value receiver so the common call patternapp.GetRoute(name).URL(params)compiles directly.Changes introduced
bytebufferpoolfor efficient string building with minimal allocations, and the greedy fallback lookup now uses precomputed string key orders to avoid repeated hot-path string conversions and extra allocations.app.GetRoute(name)indocs/api/app.md, added a release-note entry indocs/whats_new.md, and refined therouter.gogodoc forRoute.URL()to reflect directapp.GetRoute(name).URL(params)usage.app.GetRoute(name)now supportroute.URL(params)for parameterized URL generation, including named, wildcard (*), and plus (+) segments.Route.URL()complements Fiber’s existing named-route helpers in an Express-like style by letting callers generate route URLs directly from route metadata.c.GetRouteURL()conventions by returning(string, error). The implementation was refactored to a sharedbuildRouteURL(route, params)helper used by bothRoute.URL()andDefaultRes.getLocationFromRoute()so behavior stays consistent across APIs, andRoute.URL()now uses a value receiver to matchapp.GetRoute()returning aRoutevalue.app.GetRoute(name).URL(params)calls, and route fallback behavior when onlyPathis available.Additional adjustments included in this PR:
caseSensitivehandling toRoutesoRoute.URL()respects route registration and mounted sub-app behavior.!caseSensitive) → greedy fallback.+for plus params and*for wildcard params before falling back to the alternate token for compatibility.byte→stringconversions in URL generation hot paths.Route.URL()returnsErrNotFoundfor empty/zero-value routes and returnsroute.Pathwhen a route has no parsed segments.app.GetRoute(name).URL(...)usage, case-sensitive and case-insensitive behavior, exact-match precedence, greedy+handling, default greedy fallback selection, and no-parser fallback routes.Type of change
Checklist
Before you submit your pull request, please make sure you meet these requirements:
/docs/directory for Fiber's documentation.Commit formatting
Please use emojis in commit messages for an easy way to identify the purpose or intention of a commit. Check out the emoji cheatsheet here: CONTRIBUTING.md