Skip to content

🔥 feat: Implement OverrideParam override behavior for DefaultCtx#3962

Merged
ReneWerner87 merged 46 commits intogofiber:mainfrom
TheAspectDev:feature/implement-2118-updateparam
Dec 28, 2025
Merged

🔥 feat: Implement OverrideParam override behavior for DefaultCtx#3962
ReneWerner87 merged 46 commits intogofiber:mainfrom
TheAspectDev:feature/implement-2118-updateparam

Conversation

@TheAspectDev
Copy link
Contributor

@TheAspectDev TheAspectDev commented Dec 23, 2025

Description

Allows Ctx.OverrideParam to override existing route parameters while ignoring non-existing ones, and ensures proper behavior when using a nil router.

This PR reflects the mutable req.params in expressjs and adds corresponding tests and benchmarks to validate correctness and measure performance.

Changes introduced

  • 🚨 Added tests for OverrideParam:
    • Overriding existing params
    • Ignoring non-existing params
    • Nil-router behavior
  • 🚨 Added benchmark for OverrideParam
  • ♻️ Minor cleanup in ctx.go and ctx_interface_gen.go to satisfy lint rules
  • 📚 Updated docs, added c.OverrideParam

Fixes #2118

Type of change

  • New feature (adds OverrideParam override behavior)
  • Enhancement (tests and benchmarks for robustness)

🧾 Checklist

  • Followed the inspiration of the Express.js framework for new functionalities. ( req.params.q = "new-value" )
  • New feature (non-breaking change which adds functionality)
  • Enhancement (improvement to existing features and functionality)
  • Documentation update (changes to documentation)
  • Code consistency (non-breaking change which improves code reliability and robustness)
  • Benchmarks added for performance tracking
  • Added/updated unit tests

@TheAspectDev TheAspectDev requested a review from a team as a code owner December 23, 2025 22:59
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 23, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

A new public method OverrideParam is added to the Ctx interface and DefaultCtx implementation to allow modifying route parameter values. The method normalizes wildcard tokens and updates corresponding parameters with case-sensitive and case-insensitive lookup support. Comprehensive tests and API documentation are included.

Changes

Cohort / File(s) Summary
Core Implementation
ctx.go, ctx_interface_gen.go
Adds OverrideParam(name, value string) method to DefaultCtx and Ctx interface. Normalizes wildcard tokens (**1, ++1), performs parameter lookup with optional case-insensitive comparison, and updates the corresponding value in context if found. No-op if no route is matched or parameter doesn't exist.
Testing
ctx_test.go
Adds Test_Ctx_OverrideParam with subtests covering route params, wildcard variants, case sensitivity modes, and nil router scenarios. Includes Benchmark_Ctx_OverrideParam for performance measurement.
Documentation
docs/api/ctx.md, docs/whats_new.md
Documents the new method with API signature, usage examples for named and wildcard parameters, and feature inclusion in release notes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

📒 Documentation

Suggested reviewers

  • sixcolors
  • efectn
  • ReneWerner87
  • gaby

Poem

🐰 A param in flight, now we can rewrite!
Override the value, set it just right,
Wildcards and names, both handled with care,
Case-sensitive too—a feature so fair! ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ⚠️ Warning The title mentions 'UpdateParam' but the actual implementation is 'OverrideParam', and the title uses a fire emoji which adds noise. The core change (OverrideParam feature) is captured but the naming mismatch and emoji reduce clarity. Update the title to 'feat: Implement OverrideParam method for DefaultCtx' to accurately reflect the final API name and remove the emoji for clarity.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed PR successfully implements mechanism to override route parameter values at runtime via new OverrideParam method [#2118], addressing the core requirement for middleware to modify parameters visible to downstream handlers.
Out of Scope Changes check ✅ Passed All changes directly support the objective to expose route parameter override capability [#2118] with supporting tests, benchmarks, and documentation; no unrelated modifications detected.
Description check ✅ Passed The description covers the main changes (OverrideParam feature, tests, benchmarks, docs) and includes checklist items. However, most checklist items lack proper detail: the 'Migration Guide' checkbox is not addressed, and several required documentation and example sections are missing or incomplete.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @TheAspectDev, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the DefaultCtx functionality by adding an UpdateParam method, enabling the dynamic modification of route parameters during request processing. This feature provides greater flexibility for developers to manipulate request parameters on the fly, aligning with patterns seen in frameworks like Express.js. The changes are thoroughly tested with new unit tests and benchmarks to ensure correctness and optimal performance.

Highlights

  • New UpdateParam Method: Introduced UpdateParam to DefaultCtx allowing dynamic modification of route parameters, mirroring Express.js req.params behavior.
  • Parameter Override Logic: The UpdateParam method can override existing route parameters and gracefully ignores attempts to update non-existent parameters.
  • Nil Router Handling: Ensured UpdateParam behaves correctly when no route is matched (i.e., c.route is nil), preventing errors.
  • Comprehensive Testing: Added new unit tests to validate the UpdateParam method's behavior, covering parameter overriding, ignoring non-existent parameters, and nil router scenarios.
  • Performance Benchmarking: Included benchmarks for UpdateParam to measure and track its performance.
  • Documentation Update: The Ctx interface and API documentation have been updated to reflect the new UpdateParam method, including its signature and an example.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ReneWerner87 ReneWerner87 added this to the v3 milestone Dec 23, 2025
@ReneWerner87 ReneWerner87 added this to v3 Dec 23, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new UpdateParam method to the context, allowing for the modification of route parameters. The implementation is straightforward and includes comprehensive tests, benchmarks, and documentation. My main feedback is to improve the clarity and correctness of the new documentation for UpdateParam.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
docs/api/ctx.md (1)

506-508: Use fiber.Ctx as receiver type for consistency.

The signature shows *DefaultCtx as the receiver type, but for consistency with other method signatures in this documentation (e.g., lines 49, 608, 703), it should use fiber.Ctx.

🔎 Suggested fix
-```go title="Signature"
-func (c *DefaultCtx) UpdateParam(name, value string)
-```
+```go title="Signature"
+func (c fiber.Ctx) UpdateParam(name string, value string)
+```
ctx_test.go (1)

8006-8027: Consider a more focused benchmark for UpdateParam.

The current benchmark measures the entire HTTP request/response cycle (app.Test(req) includes routing, handler execution, response serialization, etc.), which adds significant overhead unrelated to UpdateParam itself.

🔎 More focused benchmark measuring UpdateParam directly
 func Benchmark_Ctx_UpdateParam(b *testing.B) {
 	app := New(Config{
 		CBOREncoder: cbor.Marshal,
 		CBORDecoder: cbor.Unmarshal,
 	})
+	c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx)
+	c.route = &Route{Params: []string{"name", "id"}}
+	c.values = [maxParams]string{"original", "123"}

-	app.Get("/user/:name/:id", func(c Ctx) error {
-		c.UpdateParam("name", "overridden")
-		return nil
-	})
-
-	req, err := http.NewRequest(http.MethodGet, "/user/original/123", http.NoBody)
-	require.NoError(b, err)
-
 	b.ReportAllocs()
+	b.ResetTimer()
 	for b.Loop() {
-		resp, err := app.Test(req)
-		require.NoError(b, err)
-		require.NoError(b, resp.Body.Close())
+		c.UpdateParam("name", "overridden")
+		c.values[0] = "original" // reset for next iteration
 	}
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 032ff5f and 0d71d87.

📒 Files selected for processing (4)
  • ctx.go
  • ctx_interface_gen.go
  • ctx_test.go
  • docs/api/ctx.md
🧰 Additional context used
📓 Path-based instructions (4)
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Prefer github.com/gofiber/utils/v2 helpers (for example, utils.Trim) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Files:

  • ctx_interface_gen.go
  • ctx.go
  • ctx_test.go
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/api/ctx.md
**/*.md

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run make markdown to lint all Markdown files when modifying code

Files:

  • docs/api/ctx.md
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

When adding Go tests, always invoke t.Parallel() at the start of each test and subtest to maximize concurrency

Files:

  • ctx_test.go
🧠 Learnings (1)
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • docs/api/ctx.md
🧬 Code graph analysis (2)
ctx.go (1)
req.go (1)
  • Params (626-632)
ctx_test.go (3)
ctx_interface_gen.go (1)
  • Ctx (18-435)
req.go (1)
  • Params (626-632)
router.go (1)
  • Route (47-68)
🔇 Additional comments (2)
ctx.go (1)

386-399: LGTM! Well-implemented defensive programming.

The implementation correctly handles the nil router case and safely updates route parameters. The bounds check i < maxParams is technically redundant since c.values is already sized at maxParams, but it's good defensive coding that adds negligible overhead.

ctx_test.go (1)

7481-7524: LGTM! Comprehensive test coverage for UpdateParam.

The test properly validates:

  • Overriding existing route parameters (nameoverridden)
  • Ignoring updates to non-existing parameters (existing)
  • Preserving unmodified parameters (id remains 123)
  • Safe handling when no route is set (nil router case)

The test structure follows best practices with t.Parallel() calls and clear subtests.

TheAspectDev and others added 2 commits December 24, 2025 02:35
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
ctx_test.go (2)

7481-7524: Good coverage for UpdateParam; consider tightening assertions in the handler.

The new test does exercise both overriding an existing param and the nil-router/no-op behavior, and t.Parallel() is correctly used on the test and both subtests as per the test guidelines. As per coding guidelines, this is good.

If you want to strengthen the behavioral guarantees a bit more:

  • In the "route_params" subtest handler, you already have access to t via closure. You could explicitly assert that a non-existent param remains empty and that the route param keys are unchanged, e.g.:
app.Get("/user/:name/:id", func(c Ctx) error {
    c.UpdateParam("name", "overridden")
    c.UpdateParam("existing", "ignored")

    require.Equal(t, "overridden", c.Params("name"))
    require.Equal(t, "123", c.Params("id"))          // or assert inside the test via JSON decode
    require.Empty(t, c.Params("existing"))
    require.Equal(t, []string{"name", "id"}, c.Route().Params)

    return c.JSON(map[string]any{
        "name": c.Params("name"),
        "id":   c.Params("id"),
        "all":  c.Route().Params,
    })
})
  • With those direct assertions in place, you can either keep or drop the "all" field from the JSON, and the require.NotContains(t, body, "existing") check becomes purely a safety net instead of the only signal for the ignored param.

Not mandatory, but it would make the test more direct about the exact invariants you care about (existing key overridden, unknown key ignored, route metadata unchanged).


8005-8023: Benchmark is focused and consistent; you can drop the per-iteration reset if not needed.

The benchmark setup mirrors existing patterns in this file (manual DefaultCtx + fixed Route.Params/values) and gives a focused view on UpdateParam itself.

If UpdateParam doesn’t depend on the previous value of c.values[0] (which it typically shouldn’t for a simple overwrite-by-name API), you can simplify and make the benchmark slightly cleaner by removing the reset from the hot loop:

c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx)
c.values = [maxParams]string{"original", "12345"}
c.route = &Route{Params: []string{"name", "id"}}

b.ReportAllocs()
b.ResetTimer()
for b.Loop() {
    c.UpdateParam("name", "changed")
}

That way you only measure the call itself, without the extra assignment cost on every iteration.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e83b799 and 158af7f.

📒 Files selected for processing (1)
  • ctx_test.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

When adding Go tests, always invoke t.Parallel() at the start of each test and subtest to maximize concurrency

Files:

  • ctx_test.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Prefer github.com/gofiber/utils/v2 helpers (for example, utils.Trim) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Files:

  • ctx_test.go
🧠 Learnings (2)
📓 Common learnings
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • ctx_test.go
🧬 Code graph analysis (1)
ctx_test.go (3)
ctx_interface_gen.go (1)
  • Ctx (18-435)
req.go (1)
  • Params (626-632)
router.go (1)
  • Route (47-68)

@TheAspectDev
Copy link
Contributor Author

/gemini summary

@gemini-code-assist
Copy link
Contributor

Summary of Changes

This pull request introduces a new UpdateParam method to the DefaultCtx context, allowing developers to dynamically modify route parameters during request processing. This enhancement provides greater flexibility in handling request parameters, drawing inspiration from frameworks like Express.js, and is supported by new tests, benchmarks, and updated documentation to ensure its correctness and performance.

Highlights

  • New UpdateParam Method: A new UpdateParam method has been implemented in DefaultCtx to allow dynamic modification of route parameter values by name, mirroring Express.js req.params behavior.
  • Parameter Override Logic: The UpdateParam method is designed to override existing route parameters while gracefully ignoring attempts to update non-existent parameters and handling scenarios where no route is matched (nil router).
  • Comprehensive Testing and Benchmarking: New unit tests have been added to validate the UpdateParam method's behavior across various scenarios, including overriding, ignoring non-existent parameters, and nil router handling. A benchmark has also been included to measure its performance.
  • Documentation Update: The Ctx interface and API documentation (docs/api/ctx.md) have been updated to reflect the new UpdateParam method, including its signature and an example.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • ctx.go
    • Added UpdateParam method to DefaultCtx to overwrite route parameter values by name.
    • Implemented logic to ignore non-defined parameter names and handle cases where c.route is nil.
  • ctx_interface_gen.go
    • Added UpdateParam(name string, value string) to the Ctx interface definition.
  • ctx_test.go
    • Added Test_Ctx_UpdateParam with subtests to verify overriding existing parameters, ignoring non-existing ones, and correct behavior with a nil router.
    • Added Benchmark_Ctx_UpdateParam to assess the performance of the new method.
  • docs/api/ctx.md
    • Added a new section for UpdateParam in the API documentation, including its signature and an example of usage.
Activity
  • CodeRabbit AI bot initiated a review, providing a walkthrough of changes, estimated review effort, suggested labels, and potential reviewers. It also noted a warning about docstring coverage.
  • Gemini Code Assist bot provided an initial summary of the pull request's changes.
  • The author, TheAspectDev, explicitly requested a summary from Gemini Code Assist.
  • Gemini Code Assist provided a review comment suggesting improvements to the UpdateParam documentation in docs/api/ctx.md for clarity, correctness, and consistency in the function signature example.

@TheAspectDev
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
ctx_test.go (1)

8007-8023: Tighten the UpdateParam benchmark setup (optional)

Two small nits you may want to address:

  • The CBOREncoder/CBORDecoder configuration on New isn’t exercised by UpdateParam; you can simplify to app := New() unless you intentionally want CBOR wired in here.
  • The forcible type assertion .(*DefaultCtx) is consistent with other benchmarks but currently lacks the //nolint:errcheck,forcetypeassert // not needed comment used elsewhere in this file; adding it would keep linters quiet and match the existing style.

Neither affects correctness of the benchmark; they’re just minor cleanliness tweaks.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 158af7f and 02bd58f.

📒 Files selected for processing (1)
  • ctx_test.go
🧰 Additional context used
📓 Path-based instructions (2)
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

When adding Go tests, always invoke t.Parallel() at the start of each test and subtest to maximize concurrency

Files:

  • ctx_test.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Prefer github.com/gofiber/utils/v2 helpers (for example, utils.Trim) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Files:

  • ctx_test.go
🧠 Learnings (2)
📓 Common learnings
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • ctx_test.go
🧬 Code graph analysis (1)
ctx_test.go (3)
ctx_interface_gen.go (1)
  • Ctx (18-435)
req.go (1)
  • Params (626-632)
router.go (1)
  • Route (47-68)
🔇 Additional comments (1)
ctx_test.go (1)

7481-7525: UpdateParam tests cover core behaviors well

The two subtests validate the intended semantics: overriding an existing route param, ignoring unknown keys, and leaving Params unchanged when using a context on an app with no routing state. Use of t.Parallel() is correct for both the parent test and subtests, and the in-handler require checks give precise guarantees around Params and Route().Params.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the UpdateParam feature, which allows for overriding route parameters. The implementation is well-structured and includes comprehensive tests and benchmarks. My review focuses on a correctness issue related to case-sensitivity in UpdateParam that could lead to inconsistent behavior. I've also provided a suggestion to improve the new benchmark by simplifying it and ensuring proper resource cleanup. Overall, this is a great addition to the framework.

@TheAspectDev
Copy link
Contributor Author

Actionable comments posted: 0

🧹 Nitpick comments (3)

ctx_test.go (1)> 8119-8140: Consider asserting the final param value after the benchmark loop

To mirror other benchmarks in this file and catch regressions in UpdateParam, you can add a quick post‑loop check that the parameter was actually updated; this won’t materially affect timing.

Proposed post-loop assertion

 func Benchmark_Ctx_UpdateParam(b *testing.B) {
@@
 	c.setMatched(true)
 
 	b.ReportAllocs()
 	b.ResetTimer()
 	for b.Loop() {
 		c.UpdateParam("name", "changed")
 	}
+
+	// Verify that UpdateParam actually updated the value
+	require.Equal(b, "changed", c.Params("name"))
 }

router_test.go (1)> 11-11: Route param max-exceed test is good; you may want to assert the panic message too

The new test correctly forces maxParams+1 parameters and ensures register panics, and the fmt import is scoped to that usage. If you want the test to lock in the formatted error (count, limit, and path), you could switch to require.PanicsWithValue (or inspect recover() inside the closure) and assert that the message contains the expected details.
Also applies to: 736-750

ctx.go (1)> 386-419: Implementation is correct, but outdated comments should be removed.

The core logic is sound:

  • Uses c.Matched() to verify route existence
  • Correctly normalizes wildcard tokens (**1, ++1)
  • Properly handles case-sensitive and case-insensitive parameter matching using utils.EqualFold

However, the comments on lines 402 and 413 stating "Prevent out-of-bounds access if route params exceed allocated values" are now outdated. With the new validation at route registration (router.go:550-552), routes cannot exceed maxParams, so the iteration over c.route.Params will never go out of bounds. These comments should be removed to avoid confusion.

🔎 Suggested cleanup

 	if c.app.config.CaseSensitive {
 		for i, param := range c.route.Params {
-			// Prevent out-of-bounds access if route params exceed allocated values
 			if param == name {
 				c.values[i] = value
 				return
 			}
 		}
 		return
 	}

 	nameBytes := utils.UnsafeBytes(name)
 	for i, param := range c.route.Params {
-		// Prevent out-of-bounds access if route params exceed allocated values
 		if utils.EqualFold(utils.UnsafeBytes(param), nameBytes) {
 			c.values[i] = value
 			return
 		}
 	}

📜 Review details

  • 8119-8140: Consider asserting the final param value after the benchmark loop: this is expected behaviour and tested by Test_Ctx_UpdateParam
  • Other two changes are acceptable and will be pushed asap

@TheAspectDev
Copy link
Contributor Author

@sixcolors

Copy link
Member

@sixcolors sixcolors left a comment

Choose a reason for hiding this comment

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

This looks good to me! 👍

@ReneWerner87
Copy link
Member

@TheAspectDev Pls also mention the new functionality with an example in the whats new md file
Otherwise its Kind of hidden for the others and less people will use it

@ReneWerner87
Copy link
Member

@gaby @sixcolors @efectn
Wdyt about the name?
@coderabbitai pls list possible names for this function
How is the name in expressjs or other rest/http frameworks?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 28, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🌐 Web query:

Express.js req.params modify parameter values how to change route parameters

💡 Result:

Short answer

  • req.params is just an object populated from the matched URL; you can mutate its properties for downstream middleware/handlers (e.g. req.params.id = 'x') but changing req.params does NOT change which route was matched or the original URL. [1][4]

How to do common tasks (examples)

  1. Preprocess/validate a param (use app.param)
  • runs before route handler and is the recommended place to normalize/replace a param value:
    app.param('id', (req, res, next, id) => {
    // load/validate/normalize
    req.params.id = normalize(id);
    next();
    });
    app.get('/user/:id', (req, res) => { res.send(req.params.id); });
    (See Express app.param docs). [2]
  1. Set a value for downstream middleware without touching params
    app.use((req, res, next) => {
    req.myValue = computeSomething(req);
    next();
    });

  2. If you must rewrite the request path (so routing changes), rewrite req.url in an early middleware or redirect
    // simple rewrite
    app.use((req, res, next) => {
    if (shouldRewrite(req)) req.url = '/new/path' + req.url; // put before routers
    next();
    });
    // or redirect to a new route
    res.redirect(301, '/new/path');
    (Rewriting req.url must be done before routing; see examples and community guidance). [5][6]

  3. Use a URL-rewrite middleware/package
    Use something like express-urlrewrite if you want declarative rewrites:
    app.use(rewrite('/:src..:dst', '/commits/:src/to/:dst'));
    (library examples). [6]

Notes / caveats

  • Mutating req.params is fine for passing normalized values to later handlers, but it will not retroactively affect route matching or Express's internal parameter parsing. If you need different routing, rewrite the URL or redirect. [1][4][5]

References
[1] Express Routing — route params explanation.
[2] Express app.param / API examples.
[4] Stack Overflow discussion: modifying req.params and alternatives.
[5] Stack Overflow: rewriting req.url in middleware.
[6] express-urlrewrite npm README (rewrite middleware).


🌐 Web query:

route parameter mutation other web frameworks Koa Hapi Fastify Gin Chi naming conventions

💡 Result:

Quick summary — how common frameworks expose route params, whether they’re directly mutable, and their naming syntax:

  • Koa (@koa/router): params available as ctx.params (plain object). You can read/assign properties on that object. Route syntax uses :name. [1]
  • Hapi: params available as request.params (plain object). Read/write is possible on that object in handlers. Route syntax uses {name} (with ?/* modifiers). [2]
  • Fastify: params available as request.params (plain object). Read/write is possible; route syntax uses :name (with ? and regex options). [3]
  • Gin (Go): access via c.Param("name") (convenience method) and c.Params (slice) — Param returns a string; mutating route params is uncommon but c.Params can be manipulated programmatically if needed. Route syntax uses :name and /*wildcard. [4]
  • Chi (Go): access via chi.URLParam(r, "name") (function that reads from request context). It’s a read accessor (not a mutable map). Route syntax uses {name} or /users/{userID}. [5]

Naming conventions: Node/JS frameworks commonly use colon-prefixed params (:id). Hapi uses curly braces ({id}). Go routers differ: Gin uses :name and /*wildcard; Chi uses {name}. Use each framework’s native style when defining routes to avoid mismatches. [1][2][3][4][5]

Sources: [1] @koa/router docs; [2] hapi docs/npm; [3] Fastify docs; [4] Gin docs; [5] go-chi README.


@ReneWerner87 Great question! Let me provide some context and alternatives:

Express.js and JavaScript Frameworks

In Express.js, req.params is simply a mutable object that you can directly modify (e.g., req.params.id = 'newValue'). Express also provides app.param() for preprocessing and normalizing parameter values before route handlers.

Other JavaScript frameworks follow similar patterns:

  • Koa: ctx.params (plain object, mutable)
  • Hapi: request.params (plain object, mutable)
  • Fastify: request.params (plain object, mutable)

Since these expose params as plain objects, there's no dedicated "update method" – you just assign directly.

Go Frameworks

Gin uses c.Param("name") for reading, while Chi uses chi.URLParam(r, "name") as a read accessor.

Possible Alternative Names for Fiber

Given that Fiber uses explicit getter/setter patterns (like Params(key) for reading), here are alternatives for the setter:

  1. SetParam – Most common setter naming convention; pairs well with getter pattern
  2. ModifyParam – Explicitly indicates mutation of existing values
  3. OverrideParam – Emphasizes replacing existing parameter values
  4. WriteParam – Clean read/write symmetry with Params()
  5. MutateParam – Very explicit about mutation
  6. PutParam – HTTP-style verb
  7. ChangeParam – Simple and clear

Recommendation

I'd suggest SetParam as it:

  • Follows standard getter/setter naming conventions
  • Is concise and intuitive
  • Pairs naturally with the existing Params(key) getter
  • Doesn't over-emphasize the "update vs create" distinction (the method already handles both gracefully)

However, UpdateParam is also perfectly valid and clearly communicates the intent to modify existing route parameters, which aligns with the PR's goal of matching Express.js mutable semantics.

What do you think? @gaby @sixcolors @efectn


🧠 Learnings used
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.

Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.

Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

@ReneWerner87
Copy link
Member

I like SetParam or OverrideParam

@gaby
Copy link
Member

gaby commented Dec 28, 2025

I like SetParam or OverrideParam

  • I like OverrideParam.

@ReneWerner87
Copy link
Member

@sixcolors @TheAspectDev ok with the new name?

@TheAspectDev
Copy link
Contributor Author

Yeah, OverrideParam seems more fitting to the action it does.

@TheAspectDev
Copy link
Contributor Author

@TheAspectDev Pls also mention the new functionality with an example in the whats new md file Otherwise its Kind of hidden for the others and less people will use it

Okay!

@TheAspectDev TheAspectDev changed the title 🔥 feat: Implement UpdateParam override behavior for DefaultCtx 🔥 feat: Implement OverrideParam override behavior for DefaultCtx Dec 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
ctx_test.go (1)

8120-8140: Add a post‑loop assertion in Benchmark_Ctx_OverrideParam

To mirror other benchmarks in this file and ensure we’re not benchmarking a no‑op, it’s worth asserting the final param value after the loop (and incidentally documenting the expected behavior):

  • Confirms OverrideParam actually mutates the runtime values with the prepared Route{Params: []string{"name","id"}}.
  • Aligns with existing benchmark style (e.g. Benchmark_Ctx_Params, Benchmark_Ctx_Accepts*, etc.).

You can do this without materially impacting benchmark semantics:

Proposed change
 func Benchmark_Ctx_OverrideParam(b *testing.B) {
 	app := New()

 	ctx := app.AcquireCtx(&fasthttp.RequestCtx{})
 	c, ok := ctx.(*DefaultCtx)
 	if !ok {
 		b.Fatal("AcquireCtx did not return *DefaultCtx")
 	}

 	defer app.ReleaseCtx(c)

 	c.values = [maxParams]string{"original", "12345"}
 	c.route = &Route{Params: []string{"name", "id"}}
 	c.setMatched(true)

 	b.ReportAllocs()
 	b.ResetTimer()
 	for b.Loop() {
 		c.OverrideParam("name", "changed")
 	}
+
+	// Sanity check that OverrideParam actually updated the value.
+	require.Equal(b, "changed", c.Params("name"))
 }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ebc1126 and 6967830.

📒 Files selected for processing (5)
  • ctx.go
  • ctx_interface_gen.go
  • ctx_test.go
  • docs/api/ctx.md
  • docs/whats_new.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • ctx.go
  • docs/api/ctx.md
🧰 Additional context used
📓 Path-based instructions (4)
**/*_test.go

📄 CodeRabbit inference engine (AGENTS.md)

When adding Go tests, always invoke t.Parallel() at the start of each test and subtest to maximize concurrency

Files:

  • ctx_test.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Prefer github.com/gofiber/utils/v2 helpers (for example, utils.Trim) when performing common operations such as string manipulation, whenever it is practical and appropriate for the surrounding code

Files:

  • ctx_test.go
  • ctx_interface_gen.go
docs/**

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Review and update the contents of the docs folder if necessary when modifying code

Files:

  • docs/whats_new.md
**/*.md

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Run make markdown to lint all Markdown files when modifying code

Files:

  • docs/whats_new.md
🧠 Learnings (14)
📓 Common learnings
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-10-08T19:06:06.583Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.
📚 Learning: 2024-11-15T07:56:21.623Z
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 3161
File: app.go:923-932
Timestamp: 2024-11-15T07:56:21.623Z
Learning: In the Fiber framework, breaking changes are acceptable when moving from version 2 to version 3, including modifications to method signatures such as in the `Test` method in `app.go`.

Applied to files:

  • ctx_test.go
📚 Learning: 2025-12-07T15:07:23.885Z
Learnt from: CR
Repo: gofiber/fiber PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-07T15:07:23.885Z
Learning: Applies to **/*_test.go : When adding Go tests, always invoke `t.Parallel()` at the start of each test and subtest to maximize concurrency

Applied to files:

  • ctx_test.go
📚 Learning: 2024-11-29T12:37:27.581Z
Learnt from: efectn
Repo: gofiber/fiber PR: 3162
File: app_test.go:893-895
Timestamp: 2024-11-29T12:37:27.581Z
Learning: In the `Test_App_ShutdownWithContext` function in `app_test.go`, the `clientDone` channel is used to synchronize the client's request completion before proceeding, eliminating the need for additional `time.Sleep` calls.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-11-10T23:44:13.704Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/adaptor/adaptor.go:111-111
Timestamp: 2024-11-10T23:44:13.704Z
Learning: In the `middleware/adaptor/adaptor.go` file of the Fiber framework, when updating context handling, replacing `c.Context()` with `c.RequestCtx()` is appropriate to access the `fasthttp.RequestCtx`.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-11-08T04:10:42.990Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3193
File: middleware/cache/cache_test.go:897-897
Timestamp: 2024-11-08T04:10:42.990Z
Learning: In the Fiber framework, `Context()` is being renamed to `RequestCtx()`, and `UserContext()` to `Context()` to improve clarity and align with Go's context conventions.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-07-26T21:00:12.902Z
Learnt from: ReneWerner87
Repo: gofiber/fiber PR: 2864
File: ctx_test.go:4816-4816
Timestamp: 2024-07-26T21:00:12.902Z
Learning: The `ParamsInt` function's behavior, including handling empty string parameters, will be addressed in future PRs as per ReneWerner87's guidance.

Applied to files:

  • ctx_test.go
📚 Learning: 2025-10-16T07:19:52.418Z
Learnt from: grivera64
Repo: gofiber/fiber PR: 3807
File: adapter_test.go:118-144
Timestamp: 2025-10-16T07:19:52.418Z
Learning: In the Fiber codebase, the linter does not allow `require` assertions from within HTTP handlers (including net/http-style handlers). Use `t.Fatalf`, `t.Errorf`, or similar `testing.T` methods for error handling inside handler functions instead.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-12-13T08:14:22.851Z
Learnt from: efectn
Repo: gofiber/fiber PR: 3162
File: hooks_test.go:228-228
Timestamp: 2024-12-13T08:14:22.851Z
Learning: In Go test files, prefer using the `require` methods from the `testify` package for assertions instead of manual comparisons and calls to `t.Fatal` or `t.Fatalf`.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-09-25T17:09:03.756Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/session/middleware_test.go:400-407
Timestamp: 2024-09-25T17:09:03.756Z
Learning: In the `Test_Session_Next` function in `middleware/session/middleware_test.go`, the variable `doNext` is properly synchronized with the `muNext` mutex for both read and write access.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/session/config.go:122-122
Timestamp: 2024-10-08T19:06:06.583Z
Learning: In `DefaultErrorHandler(c *fiber.Ctx, err error)`, since `c` is a pointer to an interface, we need to dereference `*c` when calling interface methods like `SendStatus`.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-10-08T19:06:06.583Z
Learnt from: sixcolors
Repo: gofiber/fiber PR: 3016
File: middleware/session/store.go:164-167
Timestamp: 2024-10-08T19:06:06.583Z
Learning: Unit tests in this project use testify require.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-10-16T14:00:50.724Z
Learnt from: gaby
Repo: gofiber/fiber PR: 3170
File: ctx.go:1825-1826
Timestamp: 2024-10-16T14:00:50.724Z
Learning: In the Fiber framework, the `IsProxyTrusted()` function returns `true` when `TrustProxy` is `false`, maintaining compatibility with version 2 behavior.

Applied to files:

  • ctx_test.go
📚 Learning: 2024-12-15T19:56:45.935Z
Learnt from: ckoch786
Repo: gofiber/fiber PR: 3230
File: docs/whats_new.md:944-951
Timestamp: 2024-12-15T19:56:45.935Z
Learning: Detailed usage examples and explanations for new methods like `RemoveRoute` and `RemoveRouteByName` are documented in `docs/api/app.md`, so it's unnecessary to duplicate them in `docs/whats_new.md`.

Applied to files:

  • docs/whats_new.md
🔇 Additional comments (3)
docs/whats_new.md (1)

570-570: LGTM! Clear and accurate documentation.

The description accurately captures the method's behavior and is appropriately brief for this overview document. Based on learnings, detailed examples and usage are documented in the API docs (docs/api/ctx.md), which is the correct approach.

ctx_interface_gen.go (1)

122-124: LGTM! Interface addition is well-documented.

The method comment clearly describes the overwrite behavior and explicitly states the no-op semantics when the parameter doesn't exist. Past review feedback has been addressed—the comment no longer includes unclear phrasing or implementation details. The method name "OverrideParam" is descriptive and the signature is straightforward.

ctx_test.go (1)

7481-7637: OverrideParam tests look comprehensive and match router semantics

The Test_Ctx_OverrideParam subtests nicely cover:

  • overriding existing vs non-existing params,
  • + and * wildcard params (including multi-wildcards),
  • case-sensitive vs case-insensitive routing,
  • and the nil-router/no-route-matched case via a manually acquired *DefaultCtx.

The use of t.Parallel() at the top of the main test and each subtest, plus proper AcquireCtx/ReleaseCtx usage in the nil_router case, is consistent with the rest of this file. I don’t see functional or style issues worth blocking on here.

@TheAspectDev
Copy link
Contributor Author

@ReneWerner87

@TheAspectDev
Copy link
Contributor Author

Actionable comments posted: 0

🧹 Nitpick comments (1)
📜 Review details

This behavior is expected and tested in Test_Ctx_OverrideParam

@sixcolors
Copy link
Member

@sixcolors @TheAspectDev ok with the new name?

Yes it’s good. Thanks @ReneWerner87

@ReneWerner87
Copy link
Member

Perfect, merge 🤩

@ReneWerner87 ReneWerner87 merged commit 789c56f into gofiber:main Dec 28, 2025
18 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in v3 Dec 28, 2025
@welcome
Copy link

welcome bot commented Dec 28, 2025

Congrats on merging your first pull request! 🎉 We here at Fiber are proud of you! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

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

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

🚀 [Feature]: Expose Ctx.values

5 participants