Skip to content

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

@alnuaimicoder

Description

@alnuaimicoder

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

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);

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions