json-api-dart icon indicating copy to clipboard operation
json-api-dart copied to clipboard

Support for nested filters

Open kszczek opened this issue 3 years ago • 8 comments
trafficstars

This PR adds support for nested filter parameters.

Sample usecases:

  • Retrieving shared posts based on original post's author id: filter[parent][author][id]=23461
  • Ranges: filter[price][min]=10&filter[price][max]=20

kszczek avatar May 24 '22 18:05 kszczek

Yeah we could use the type checking with Object. Actually while changing dynamics to Objects I've found a potential bug with the remove method because of the dynamic type.

kszczek avatar May 24 '22 19:05 kszczek

Thanks a lot! I will take a deeper look into the PR later today or tomorrow.

f3ath avatar May 24 '22 21:05 f3ath

So at last I found some time to think about this change. First of all, thank you for the PR. I appreciate your effort. However, It seems that changing the signature of the Filter class would be BC-breaking. E.g. this code will not compile after the change:

String value = Filter.fromUrl(...)['my_key'];

To release a new major version seems to be an overkill in this case. Another concern is that the JSON API standard explicitly says that it's agnostic of the actual filter implementation. Perhaps I should not have added Request.filter() method at all, since it makes this implementation kind of opinionated, which is not what I want. In this context, adding even more complex logic to this filtering strategy doesn't seem right.

I assume you're already using the extended implementation of the filter in your projects. It should be easy to implement your analog of the asQueryParameters getter and add the values to the request.query directly.

f3ath avatar Jun 02 '22 03:06 f3ath

Yeah, I agree with keeping the filtering mechanism agnostic, although we still could make it easier for developers to add their own filter implementations, for example we could remove the Filter class implementation and make it abstract like so:

abstract class Filter {
  Map<String, String> get asQueryParameters;
}

Then the routing client's methods would accept a Filter filter instead of Map<String, String> filter, this would allow developers to stick in their own filter implementations, this would be a breaking change but I think it's an important one, because if there was a way to implement custom filters without modyfing the package code I wouldn't have opened this PR. What do you think about this?

kszczek avatar Jun 02 '22 08:06 kszczek

plus this is technically an agnostic approach, because there is no implementation, so we would still be compliant with JSON:API specs, although maybe we could keep some sample filter implementations in another namespace, maybe unofficial?

kszczek avatar Jun 02 '22 08:06 kszczek

Hey there... Just wanted to add: Did you think of support for more complex filter structures?

JsonApiDotNet has a very sophisticated and mighty filter definition syntax, that is also specs compilant... Here is a simple and a pretty complex example:

# simple
/users?filter=equals(displayName,null)

# complex
/articles?include=author,tags&filter=equals(author.lastName,'Smith')&filter[tags]=any(label,'tech','design')

See https://www.jsonapi.net/usage/reading/filtering.html for details.

Would this be even possible to specify ATM? E.g. be defining filters as strings manually?

sandreas avatar Aug 26 '22 15:08 sandreas

In the current implementation, most of the methods in the RoutingClient have the query parameter which you can use to pass arbitrary data.

f3ath avatar Sep 09 '22 22:09 f3ath

I'm trying to come up with a new version which will support JSON: API 1.1. What do you guys think of this approach to passing query parameters? https://github.com/f3ath/json-api-dart/blob/8cbc0a6fe8bd7f19d6e99523dea41ddea8cd2879/test/unit/client/client_test.dart#L57

f3ath avatar Sep 11 '22 15:09 f3ath

Closing as this has been stale for a while.

f3ath avatar Jun 02 '24 19:06 f3ath