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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

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.

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