Skip to content

🔥 feat: Added support for custom binding precedence#4544

Open
aryan262 wants to merge 12 commits into
gofiber:mainfrom
aryan262:support-custom-precedence
Open

🔥 feat: Added support for custom binding precedence#4544
aryan262 wants to merge 12 commits into
gofiber:mainfrom
aryan262:support-custom-precedence

Conversation

@aryan262

@aryan262 aryan262 commented Jul 19, 2026

Copy link
Copy Markdown

Description

Currently, Fiber's ctx.Bind().All() method binds values from request sources using a strict, hardcoded precedence (URI params -> Body -> Query -> Headers -> Cookies). If conflicting data exists across these sources, developers have no mechanism to override which source takes priority on a per-struct basis.

This PR introduces support for a new struct tag, binding_source, which allows developers to define a custom precedence order for data binding. For example: binding_source:"query,header,cookie,body,uri".

To maintain Fiber's strict zero-allocation and high-performance standards, this implementation avoids parsing struct tags or splitting strings on the hot path for every request. Instead, it utilizes a highly optimized internal caching layer (bindingPrecedenceCache via sync.Map) to process and store the precedence configuration exactly once per reflect.Type.

Fixes # (issue)

Changes introduced

List the new features or adjustments introduced in this pull request. Provide details on benchmarks, documentation updates, changelog entries, and if applicable, the migration guide.

  • Benchmarks: Describe any performance benchmarks and improvements related to the changes.
  • Documentation Update: Detail the updates made to the documentation and links to the changed files.
  • Changelog/What's New: Include a summary of the additions for the upcoming release notes.
  • Migration Guide: If necessary, provide a guide or steps for users to migrate their existing code to accommodate these changes.
  • API Alignment with Express: Explain how the changes align with the Express API.
  • API Longevity: Discuss the steps taken to ensure that the new or updated APIs are consistent and not prone to breaking changes.
  • Examples: Provide examples demonstrating the new features or changes in action.

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • Enhancement (improvement to existing features and functionality)
  • Documentation update (changes to documentation)
  • Performance improvement (non-breaking change which improves efficiency)
  • Code consistency (non-breaking change which improves code reliability and robustness)

Checklist

Before you submit your pull request, please make sure you meet these requirements:

  • Followed the inspiration of the Express.js framework for new functionalities, making them similar in usage.
  • Conducted a self-review of the code and provided comments for complex or critical parts.
  • Updated the documentation in the /docs/ directory for Fiber's documentation.
  • Added or updated unit tests to validate the effectiveness of the changes or new features.
  • Ensured that new and existing unit tests pass locally with the changes.
  • Verified that any new dependencies are essential and have been agreed upon by the maintainers/community.
  • Aimed for optimal performance with minimal allocations in the new code.
  • Provided benchmarks for the new code to analyze and improve upon.

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

@aryan262
aryan262 requested a review from a team as a code owner July 19, 2026 10:34
@welcome

welcome Bot commented Jul 19, 2026

Copy link
Copy Markdown

Thanks for opening this pull request! 🎉 Please check out our contributing guidelines. If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Bind.All now supports struct-tag-defined binding-source precedence, caches parsed precedence metadata, preserves default ordering when tags are absent, and adds tests and documentation for the behavior.

Changes

Custom binding precedence

Layer / File(s) Summary
Precedence tag resolution
bind.go, docs/api/bind.md
Parses comma-separated binding_source tags into cached URI, body, query, header, and cookie precedence entries, with corresponding API documentation.
Bind.All precedence integration
bind.go, bind_test.go
Builds binding functions from custom precedence when present, retains the default order otherwise, and tests query and header selection.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RequestType
  participant BindAll
  participant BindingSources
  RequestType->>BindAll: binding_source precedence tag
  BindAll->>BindingSources: invoke sources in configured order
  BindingSources-->>BindAll: populated destination fields
Loading

Possibly related PRs

Suggested reviewers: gaby, sixcolors, renewerner87, efectn

Poem

A bunny hops through query and header bright,
Tags set the order just right.
Body and cookies wait their turn,
While cached paths swiftly learn.
Bindings merge, tests cheer—
“Precedence is clear!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: custom binding precedence support.
Description check ✅ Passed The description covers the feature, motivation, implementation, and required template sections, with only some non-critical details left sparse.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@aryan262 aryan262 changed the title added support custom precedence with an optional binding_source tag 🔥 feat: support custom binding precedence with binding_source tag Jul 19, 2026
@ReneWerner87

Copy link
Copy Markdown
Member

@aryan262 Sounds like a cool feature, but we definitely need documentation; otherwise, no one will know about it and therefore no one will use it.

@aryan262

Copy link
Copy Markdown
Author

@ReneWerner87 I am new to this repo, how should I add documentation for this PR ?

@ReneWerner87

Copy link
Copy Markdown
Member

here is the location of the docs files
https://github.com/gofiber/fiber/tree/main/docs

and this is the result https://docs.gofiber.io/

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.77419% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.24%. Comparing base (ce323d0) to head (278f94a).

Files with missing lines Patch % Lines
bind.go 96.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4544      +/-   ##
==========================================
+ Coverage   93.19%   93.24%   +0.05%     
==========================================
  Files         140      140              
  Lines       14567    14625      +58     
==========================================
+ Hits        13575    13637      +62     
+ Misses        619      615       -4     
  Partials      373      373              
Flag Coverage Δ
unittests 93.24% <96.77%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gaby gaby changed the title 🔥 feat: support custom binding precedence with binding_source tag 🔥 feat: Ass support custom binding precedence Jul 19, 2026
@gaby gaby changed the title 🔥 feat: Ass support custom binding precedence 🔥 feat: Ass support for custom binding precedence Jul 19, 2026
@gaby

gaby commented Jul 19, 2026

Copy link
Copy Markdown
Member

@aryan262 The linter workflow is failing.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/api/bind.md (1)

74-98: 📐 Maintainability & Code Quality | 🔵 Trivial

Run make markdown before merge. This repository has a markdown target that checks all **/*.md files, including docs/api/bind.md.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/api/bind.md` around lines 74 - 98, Run the repository’s markdown
formatting or validation step with make markdown after updating the bind
documentation, and resolve any reported formatting issues in docs/api/bind.md
before merging.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/api/bind.md`:
- Line 97: Update the Fiber precedence-cache note in Bind.All documentation to
remove the claim of zero-allocation efficiency. State only that precedence
resolution is cached per reflect.Type to reduce repeated parsing overhead.

---

Nitpick comments:
In `@docs/api/bind.md`:
- Around line 74-98: Run the repository’s markdown formatting or validation step
with make markdown after updating the bind documentation, and resolve any
reported formatting issues in docs/api/bind.md before merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fae9e1c0-64a3-4017-a830-e8659e78f994

📥 Commits

Reviewing files that changed from the base of the PR and between a126f7c and ac7353a.

📒 Files selected for processing (1)
  • docs/api/bind.md

Comment thread docs/api/bind.md Outdated
@aryan262 aryan262 changed the title 🔥 feat: Ass support for custom binding precedence 🔥 feat: Added support for custom binding precedence Jul 19, 2026
@aryan262

Copy link
Copy Markdown
Author

@gaby can you check now if it's failing. I'll check

@gaby

gaby commented Jul 19, 2026

Copy link
Copy Markdown
Member

Error: bind_test.go:2952:1: File is not properly formatted (gofmt)

@aryan262

Copy link
Copy Markdown
Author

@gaby I think it was because of an extra line expected in that file. Fixed it

@gaby gaby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for picking up the binding_source TODO — the feature is legitimately useful and the per-reflect.Type caching is the right design: tag parsing never runs on the hot path after the first request per type, All() already guarantees a pointer-to-struct before getBindingPrecedence runs (so NumField() can't panic), and the cached slice is never mutated after store, so sharing it is safe.

That said, requesting changes for a few correctness/usability gaps before this merges:

Main issues (details inline):

  1. Invalid tag tokens are silently dropped — a typo silently changes which sources get bound, and an all-invalid tag silently falls back to the default order. This should fail loudly.
  2. Undocumented/untested semantics — omitted sources are never bound, duplicates bind twice, and first-tag-wins is field-order dependent when multiple fields carry the tag.
  3. Docs example leaks the marker fieldc.JSON(req) will emit "BindingSource":{}; needs json:"-" at minimum.
  4. Lint/style — the C-style for loop will trip the modernize linter, and the docs note should use a :::info admonition like the rest of the file.
  5. Benchmarks — the PR checks the Benchmarks box but adds none; every existing All() call now pays a sync.Map.Load, so it'd be good to show the default path didn't regress and add one for the custom path.

None of these are structural — the core approach can stay as-is. 👍


Generated by Claude Code

Comment thread bind.go Outdated
Comment thread bind.go Outdated
Comment thread bind.go Outdated
Comment thread bind.go Outdated
Comment thread docs/api/bind.md Outdated
Comment thread docs/api/bind.md Outdated
Comment thread bind_test.go
@aryan262
aryan262 requested a review from gaby July 19, 2026 17:20

@gaby gaby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-reviewed at 0370b26 — this update addresses all of the previous round's feedback: invalid tokens now error (with negative-result caching, nice touch), multiple tags error instead of being field-order dependent, duplicates are deduped, the modernize loop style is fixed, the slice is pre-sized and hasBody extracted, the docs example no longer leaks a marker field into JSON, the note uses :::info with the partial-list/unknown-source semantics spelled out, and the test/benchmark coverage is now thorough. 👏

I also verified locally (fork CI hasn't run yet):

  • ✅ All Test_Bind_All* tests pass.
  • ✅ No regression on the default path — BenchmarkBind_All actually improved slightly vs main (59 → 57 allocs/op, ~2056 → ~1991 B/op), thanks to the pre-sized slice.
  • Lint will fail CI — golangci-lint v2.12.2 (the version pinned in .github/workflows/lint.yml) reports 6 issues, all in bind_test.go: 5× errcheck on the bare .(*DefaultCtx) assertions, and 1× gofmt on the benchmark's User struct alignment. Both are mechanical fixes — details inline.

Requesting changes only for the two lint items; the remaining inline comments are optional nits (stale cache comment, empty-token error message, require.EqualError, and a non-blocking note about the error path skipping returnErr). Once lint is green this looks good to me.


Generated by Claude Code

Comment thread bind_test.go Outdated
Comment thread bind_test.go
Comment thread bind.go Outdated
Comment thread bind.go
Comment thread bind.go
Comment thread bind_test.go Outdated
@aryan262
aryan262 requested a review from gaby July 20, 2026 12:27

@gaby gaby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

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

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants