ardalis / ardalis/Specification
Feature: Add Token-Based Dynamic Filtering and Hybrid Specifications Support
- Dominant language
- C#
- Stars
- 2.3k
- Forks
- 262
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
Add support for parsing dynamic filters, sorting, and pagination from query parameters or JSON (token-based syntax) and integrating them with existing Specification Pattern implementations.
This feature would allow combining **dynamic filtering** (user-provided queries) with **business rules** (static specifications) in a hybrid approach, providing flexibility similar to GraphQL but within the familiar Specification framework.
---
## Motivation
- Currently, specifications are defined statically in code. Dynamic scenarios (e.g., filtering from query strings in REST APIs) require custom code outside the library.
- Many APIs need **runtime filters** combined with **predefined business rules** (e.g., soft-delete, multi-tenancy).
- Adding token-based parsing (e.g., `Name~contains~foo;Priority~eq~high`) would:
- Reduce boilerplate code for parsing query strings.
- Enable hybrid use: static specs + dynamic filters together.
- Provide a consistent, extensible pattern for advanced querying.
---
## Proposed Design
1. **TokenQuery Model**
Encapsulates filters, sorting, pagination, and selected fields parsed from query strings or JSON.
2. **TokenQueryParser**
Converts query strings or JSON into `TokenQuery` objects.
3. **Extensions for Specifications**
- `spec.ApplyTokenQuery(tokenQuery)`
- Merges dynamic filters with existing static specs.
4. **Supported Operations**
- Filtering: eq, neq, contains, startswith, endswith, gt, lt, between
- Sorting: `field:asc`, `field:desc`
- Pagination: page + pageSize
- Field selection (optional)
5. **Hybrid Support**
Specifications define static rules (e.g., `ActiveTodosSpec`)
TokenQuery applies additional runtime filters.
---
## Example
```csharp
var tokenQuery = TokenQueryParser.FromQueryString("?filter=Name~contains~work;IsComplete~eq~true&sort=Priority:asc&page=1&pageSize=10");
var spec = new ActiveTodosSpec()
.ApplyTokenQuery(tokenQuery);
var result = await repository.ListAsync(spec);
Contributor guide
Research direction
No files or tests are named. Start by reading the existing Specification Pattern and repository APIs, then map the proposed TokenQuery model, TokenQueryParser, and ApplyTokenQuery extension onto them. Done means query-string or JSON filters, sorting, pagination, and hybrid static-plus-dynamic specifications support the listed operations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100