ardalis / ardalis/Specification

Feature: Add Token-Based Dynamic Filtering and Hybrid Specifications Support

Open
#525 1 comment 0 reactions 0 assignees View on GitHub
enhancement
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.