Skip to content

refactor(paging): add paging to params and middleware BED-8597#2974

Open
mistahj67 wants to merge 1 commit into
mainfrom
BED-8597
Open

refactor(paging): add paging to params and middleware BED-8597#2974
mistahj67 wants to merge 1 commit into
mainfrom
BED-8597

Conversation

@mistahj67

@mistahj67 mistahj67 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

  • Adds paging keys (skip, limit) to the bhctx
  • Adds WithPaging middleware for future slice endpoints

Describe your changes in detail

Motivation and Context

Resolves BED-8597

Why is this change required? What problem does it solve?

How Has This Been Tested?

Please describe in detail how you tested your changes.
Include details of your testing environment, and the tests you ran to
see how your change affects other areas of the code, etc.

Screenshots (optional):

Types of changes

  • Chore (a change that does not modify the application functionality)

Checklist:

Summary by CodeRabbit

  • New Features
    • Added paging support to API routes via skip and limit query parameters, with configurable defaults and validation.
    • Supports an optional “unlimited results” mode using limit = -1 (when enabled).
  • Bug Fixes
    • Requests with invalid paging parameters now immediately return 400 Bad Request with clear error details.
    • Validated paging values are stored in the request context for consistent downstream handling.
  • Tests
    • Added unit tests covering parsing, defaults, unlimited handling, and validation error cases.

@mistahj67 mistahj67 self-assigned this Jul 9, 2026
@mistahj67 mistahj67 added the api A pull request containing changes affecting the API code. label Jul 9, 2026
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 45bb9d47-5696-4226-b64e-e9f8c7ca6226

📥 Commits

Reviewing files that changed from the base of the PR and between efbdad9 and aeafbf3.

📒 Files selected for processing (5)
  • cmd/api/src/api/middleware/paging.go
  • cmd/api/src/api/router/router.go
  • cmd/api/src/bhctx/bhctx.go
  • packages/go/params/paging.go
  • packages/go/params/paging_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • cmd/api/src/bhctx/bhctx.go
  • cmd/api/src/api/middleware/paging.go
  • packages/go/params/paging_test.go
  • cmd/api/src/api/router/router.go
  • packages/go/params/paging.go

📝 Walkthrough

Walkthrough

Adds a reusable paging parser with validation and tests, extends bhctx.Context with Skip and Limit, and wires paging middleware into routes.

Changes

Paging Support

Layer / File(s) Summary
Paging parser contract and implementation
packages/go/params/paging.go, packages/go/params/paging_test.go
Defines configurable paging parsing, validation errors, defaults, unlimited-result handling, and tests for valid and invalid query parameters.
Context fields for paging
cmd/api/src/bhctx/bhctx.go
Adds Skip and Limit integer fields to the request context.
Middleware and router wiring
cmd/api/src/api/middleware/paging.go, cmd/api/src/api/router/router.go
Validates paging parameters, returns 400 responses for invalid input, stores valid values in context, and exposes Route.WithPaging.

Estimated code review effort: 2 (Simple) | ~15 minutes

Suggested reviewers: superlinkx, cweidenkeller

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Route
  participant PagingMiddleware
  participant PagingParser
  participant Handler
  Client->>Route: Request with paging query parameters
  Route->>PagingMiddleware: Invoke configured middleware
  PagingMiddleware->>PagingParser: ParseAndValidate query values
  PagingParser-->>PagingMiddleware: Validated paging or error
  alt Invalid parameters
    PagingMiddleware-->>Client: 400 Bad Request
  else Valid parameters
    PagingMiddleware->>Handler: Set context paging and continue
    Handler-->>Client: Process request
  end
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding paging support to params and middleware.
Description check ✅ Passed The description matches the template and includes the required sections, ticket, change type, and checklist, though testing details are sparse.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BED-8597

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

@mistahj67 mistahj67 marked this pull request as ready for review July 9, 2026 20:31
@mistahj67 mistahj67 marked this pull request as draft July 9, 2026 20:36

@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)
cmd/api/src/api/middleware/paging.go (1)

39-46: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hoist paging/err and drop the else-after-return.

Per coding guidelines, variable initializations should be hoisted to the top of the function where possible; this also removes the unnecessary else after an early return.

♻️ Proposed refactor
 return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
-	if paging, err := parser.ParseAndValidate(request.URL.Query()); err != nil {
-		api.WriteErrorResponse(request.Context(), api.BuildErrorResponse(http.StatusBadRequest, fmt.Sprintf(api.FmtErrorResponseDetailsBadQueryParameters, err), request), response)
-		return
-	} else {
-		bhCtx := bhctx.Get(request.Context())
-		bhCtx.Skip = paging.Skip
-		bhCtx.Limit = paging.Limit
-	}
+	paging, err := parser.ParseAndValidate(request.URL.Query())
+	if err != nil {
+		api.WriteErrorResponse(request.Context(), api.BuildErrorResponse(http.StatusBadRequest, fmt.Sprintf(api.FmtErrorResponseDetailsBadQueryParameters, err), request), response)
+		return
+	}
+
+	bhCtx := bhctx.Get(request.Context())
+	bhCtx.Skip = paging.Skip
+	bhCtx.Limit = paging.Limit
 
 	next.ServeHTTP(response, request)
 })

As per coding guidelines: "Group variable initializations in a var ( ... ) block and hoist them to the top of the function when possible."

🤖 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 `@cmd/api/src/api/middleware/paging.go` around lines 39 - 46, Hoist the paging
parse variables in the paging middleware and remove the unnecessary else after
the early return. In the middleware function that calls parser.ParseAndValidate
and writes the bad request response, declare paging and err together in a var
block at the top when possible, then keep the validation/error handling as a
straight if-return flow and assign bhCtx.Skip and bhCtx.Limit immediately after
success.

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 `@packages/go/params/paging.go`:
- Around line 69-71: The PagingValidationError.Error method is only formatting
Err and Value, so it drops the actual Parameter and produces the wrong field
name for custom SkipKey values. Update Error() to include the Parameter when
present, and keep the message consistent with how
cmd/api/src/api/middleware/paging.go forwards the validation error into the 400
response. Use PagingValidationError, Parameter, and ErrInvalidSkip to locate the
fix.

---

Nitpick comments:
In `@cmd/api/src/api/middleware/paging.go`:
- Around line 39-46: Hoist the paging parse variables in the paging middleware
and remove the unnecessary else after the early return. In the middleware
function that calls parser.ParseAndValidate and writes the bad request response,
declare paging and err together in a var block at the top when possible, then
keep the validation/error handling as a straight if-return flow and assign
bhCtx.Skip and bhCtx.Limit immediately after success.
🪄 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 YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 90e236f3-9edb-4ca8-9f2f-0792337d63bb

📥 Commits

Reviewing files that changed from the base of the PR and between 5c9a331 and f628bd9.

📒 Files selected for processing (5)
  • cmd/api/src/api/middleware/paging.go
  • cmd/api/src/api/router/router.go
  • cmd/api/src/bhctx/bhctx.go
  • packages/go/params/paging.go
  • packages/go/params/paging_test.go

Comment on lines +69 to +71
func (s *PagingValidationError) Error() string {
return fmt.Sprintf("%s: %q", s.Err, s.Value)
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Error() never surfaces the actual Parameter, causing misleading messages for custom SkipKey.

ErrInvalidSkip's wording hardcodes "skip", but SkipKey is configurable. When a caller configures a different key (e.g. "offset") and validation fails, Error() still returns "skip must be a non-negative integer: ...", even though the offending query parameter was offset. The middleware at cmd/api/src/api/middleware/paging.go (Line 40) forwards this string directly into the 400 response without using Parameter, so end users will see the wrong parameter name referenced in their error.

🐛 Proposed fix
 func (s *PagingValidationError) Error() string {
-	return fmt.Sprintf("%s: %q", s.Err, s.Value)
+	return fmt.Sprintf("%s: %s=%q", s.Err, s.Parameter, s.Value)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (s *PagingValidationError) Error() string {
return fmt.Sprintf("%s: %q", s.Err, s.Value)
}
func (s *PagingValidationError) Error() string {
return fmt.Sprintf("%s: %s=%q", s.Err, s.Parameter, s.Value)
}
🤖 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 `@packages/go/params/paging.go` around lines 69 - 71, The
PagingValidationError.Error method is only formatting Err and Value, so it drops
the actual Parameter and produces the wrong field name for custom SkipKey
values. Update Error() to include the Parameter when present, and keep the
message consistent with how cmd/api/src/api/middleware/paging.go forwards the
validation error into the 400 response. Use PagingValidationError, Parameter,
and ErrInvalidSkip to locate the fix.

@mistahj67 mistahj67 force-pushed the BED-8597 branch 2 times, most recently from d1e927c to efbdad9 Compare July 9, 2026 22:16
@mistahj67 mistahj67 marked this pull request as ready for review July 10, 2026 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api A pull request containing changes affecting the API code.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants