Skip to content

Allow derived inclusion chains in filter/sort/page query strings #1756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 19, 2025

Conversation

bkoelman
Copy link
Member

@bkoelman bkoelman commented Aug 10, 2025

This PR adds support for using derived inclusion chains in filter/sort/page query string parameters.

For example:

[Resource]
public abstract class Vehicle : Identifiable<long>
{
}

[Resource]
public sealed class Boat : Vehicle
{
}

[Resource]
public sealed class Car : Vehicle
{
    [HasMany]
    public ISet<Wheel> Wheels { get; set; } = new HashSet<Wheel>();
}

[Resource]
public sealed class Wheel : Identifiable<long>
{
    [Attr]
    public decimal Radius { get; set; }
}

The following query now applies the specified filter only on cars:

GET /vehicles?include=wheels&filter[wheels]=greaterThan(radius,'5')

Before, the request would fail with HTTP 400:

The specified filter is invalid.
Field 'wheels' does not exist on resource type 'vehicles'.

Minor breaking API changes:

  • QueryStringParameterScopeExpression.Scope: Type changed from ResourceFieldChainExpression? to IncludeExpression?.
  • PaginationElementQueryStringValueExpression.Scope: Type changed from ResourceFieldChainExpression? to IncludeExpression?.
  • IQueryStringParameterScopeParser.Parse: removed pattern and options parameters.
  • IncludeParser.ParseInclude / QueryStringParameterScopeParser.ParseQueryStringParameterScope: removed source parameter, which is now available as a property on the base class.

The breaking changes are required to support multiple derived relationships in an inclusion chain. Parsing scopes in filter/sort/page now works similarly to how the value of the include query string parameter is parsed.

For example, assume that type Truck also has a Wheels to-many relationship. The wheels scope in filter[wheels] is now parsed into two inclusion chains: one for Car and one for Truck, so that the filter can be applied to both. To visualize the change, call ToFullString() on the expression.

Fixes #1642.

QUALITY CHECKLIST

@bkoelman bkoelman force-pushed the derived-inclusion-chains branch from 9c5b3b3 to c7ca5b4 Compare August 10, 2025 14:03
@bkoelman bkoelman marked this pull request as ready for review August 10, 2025 14:27
@bkoelman
Copy link
Member Author

Holding off on the merge until the coverage diff works again. Tracked at codecov/codecov-action#1852.

@bkoelman bkoelman force-pushed the derived-inclusion-chains branch 2 times, most recently from 4763035 to fb82615 Compare August 19, 2025 00:14
Copy link

codecov bot commented Aug 19, 2025

Codecov Report

❌ Patch coverage is 96.68874% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.06%. Comparing base (f20d94d) to head (fb82615).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...otNetCore/Queries/Parsing/QueryExpressionParser.cs 94.89% 3 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1756      +/-   ##
==========================================
- Coverage   92.06%   92.06%   -0.01%     
==========================================
  Files         475      475              
  Lines       14699    14722      +23     
  Branches     2322     2331       +9     
==========================================
+ Hits        13533    13554      +21     
- Misses        765      766       +1     
- Partials      401      402       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bkoelman bkoelman merged commit 23be010 into master Aug 19, 2025
28 checks passed
@bkoelman bkoelman deleted the derived-inclusion-chains branch August 19, 2025 00:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Resource inheritance: can't use relationships from derived types in filter/sort/pagination chain
1 participant