Skip to content

refactor(filters): add filter pkg and middleware for slice architecture BED-8594 - #2943

Merged
mistahj67 merged 6 commits into
mainfrom
BED-8594
Jul 7, 2026
Merged

refactor(filters): add filter pkg and middleware for slice architecture BED-8594#2943
mistahj67 merged 6 commits into
mainfrom
BED-8594

Conversation

@mistahj67

@mistahj67 mistahj67 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

  • Ports request param filter parsing it's own agnostic package
  • Moves filter parsing into middleware to centralize bespoke boilerplate
  • Stores filter info on the bhctx for later use in db layer
  • Does not update existing filter, should happen dynamically as endpoints are refactored to slice arch

Describe your changes in detail

Motivation and Context

Resolves BED-8594

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 support for filtering API query results using validated query parameters.
    • Routes can now opt into filter handling, with parsed filters available in request context for downstream use.
  • Bug Fixes

    • Returns a clear 400 Bad Request when filter parameters are invalid.
    • Improves error messages for unsupported fields, unsupported operators, and malformed filter syntax.
    • Unrecognized filter parameters can be safely ignored where configured, while valid filters continue to work.

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

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 20 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: c8048022-7637-4cec-a83e-9e4cb1ce7b4f

📥 Commits

Reviewing files that changed from the base of the PR and between d60531e and ae3a55e.

📒 Files selected for processing (1)
  • cmd/api/src/api/middleware/filters.go
📝 Walkthrough

Walkthrough

Introduces a new filters package defining filter operators, validation errors, and a query-parameter parser/validator (ParseAndValidate), plus tests. Adds FilterMiddleware for parsing/validating request query filters, wires a WithFilters router method, and extends the BloodHound request context with a Filters field.

Changes

Filters Feature

Layer / File(s) Summary
Filter contracts and validation errors
packages/go/filters/filter.go
Defines FilterOperator constants, ValidationError, ParseFilterOperator, FilterSetOperator, Filter, Filters, FilterableField, and the Filterable interface.
Query parameter parser
packages/go/filters/parser.go, packages/go/filters/parser_test.go
Implements QueryParameterFilterParser.ParseAndValidate to parse/validate query values into Filters, with tests covering parsing, enrichment, ignored parameters, and error cases.
Middleware, router, and context wiring
cmd/api/src/api/middleware/filters.go, cmd/api/src/api/router/router.go, cmd/api/src/bhctx/bhctx.go
Adds FilterMiddleware to parse/validate request filters and return 400 on failure, adds Route.WithFilters to attach the middleware, and adds Context.Filters to store parsed filters.

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

Sequence Diagram(s)

sequenceDiagram
participant Client
participant Route
participant FilterMiddleware
participant QueryParameterFilterParser
participant BHContext
participant Handler
Client->>Route: HTTP request with query params
Route->>FilterMiddleware: invoke middleware chain
FilterMiddleware->>QueryParameterFilterParser: ParseAndValidate(request.URL.Query())
QueryParameterFilterParser-->>FilterMiddleware: Filters or ValidationError
alt validation error
  FilterMiddleware-->>Client: 400 Bad Request
else success
  FilterMiddleware->>BHContext: set Filters
  FilterMiddleware->>Handler: call next handler
end
Loading

Possibly related PRs

  • SpecterOps/BloodHound#2759: The SQL filter builder there consumes filters.Filters (including IsStringData) produced by this PR's parsing pipeline.

Suggested reviewers: cweidenkeller

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and directly reflects the main change: the new filter package and middleware for slice architecture.
Description check ✅ Passed The description follows the template and includes the required sections, issue reference, change summary, type, and checklist; only test details are sparse.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch BED-8594

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

@mistahj67
mistahj67 marked this pull request as ready for review July 1, 2026 19:57

@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: 2

🤖 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 `@cmd/api/src/api/middleware/filters.go`:
- Around line 38-58: `FilterMiddleware` is rebuilding the query filter parser on
every request instead of once when the middleware is created. Move the
`filters.NewQueryParameterFilterParser(append(model.IgnoreFilters(),
model.AllPaginationQueryParameters()...)...)` construction out of the inner
`http.HandlerFunc` closure in `FilterMiddleware`, so the parser and its regex
compilation happen once per route registration. Keep the request-time logic in
the closure using the prebuilt parser, while preserving the existing
`ParseAndValidate` and `bhctx.Get` behavior.

In `@packages/go/filters/parser.go`:
- Around line 34-39: The QueryParameterFilterParser currently accepts partial
matches from junk input and uses an ambiguous value character class in
NewQueryParameterFilterParser. Update the valuePattern in
QueryParameterFilterParser to anchor the full operator:value expression so
FindStringSubmatch only matches complete filters, and replace the current value
class with an explicit RE2-safe class that matches the documented syntax. Keep
the fix localized to NewQueryParameterFilterParser and the parsing logic that
consumes valuePattern.
🪄 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: d3a0a5ec-4e3f-4345-86d7-6b1f5dda7441

📥 Commits

Reviewing files that changed from the base of the PR and between aa6e331 and 233c3a0.

📒 Files selected for processing (7)
  • cmd/api/src/api/constant.go
  • cmd/api/src/api/middleware/filters.go
  • cmd/api/src/api/router/router.go
  • cmd/api/src/bhctx/bhctx.go
  • packages/go/filters/filter.go
  • packages/go/filters/parser.go
  • packages/go/filters/parser_test.go

Comment thread cmd/api/src/api/middleware/filters.go
Comment thread packages/go/filters/parser.go
Comment thread cmd/api/src/api/middleware/filters.go Outdated

@superlinkx superlinkx 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.

Approving in case I get pulled in other directions. I'd like the CR comment addressed and you may want to use AsType (it's a nit, but it is nicer if you want to use it). Otherwise, ship it

@mistahj67
mistahj67 merged commit f047b76 into main Jul 7, 2026
12 checks passed
@mistahj67
mistahj67 deleted the BED-8594 branch July 7, 2026 22:11
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

api A pull request containing changes affecting the API code.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants