yahoo / elide

Elide is a Java library that lets you stand up a GraphQL/JSON-API web service with minimal effort.
https://elide.io
Other
1k stars 229 forks source link

Allow defining nested filters in JSON API #688

Open clayreimann opened 6 years ago

clayreimann commented 6 years ago

Currently, relationships with the same type on both sides are subjected to the same filters which is not always desirable. Consider the following model.

@Entity
@Include(rootLevel = true)
@SharePermission
public class Node {
    @Getter @Setter long id;
    @Getter @Setter Node parent;
    @Getter @Setter Set<Node> children;
}

JSON API is currently unable to query all nodes without a parent and have the children attribute populated in the returned data. This is because DataStoreTransaction::loadObjects applies the same filter to both the root collection as well as the relationship collection.

One possible expression of such a query is:

/api/v1/node/?filter[node]=parent=isnull=true&filter[node.children]=parent=isnull=false
clayreimann commented 6 years ago

Thoughts @aklish @DennisMcWherter?

DennisMcWherter commented 6 years ago

To be clear, the problem is filtering at the root and then filtering children of the same type? The root cause of this behavior is filtering the root collection requires a global filter applied to all instances of that type, correct?

I definitely think this should be fixed; we're limiting the API's flexibility to be expressive as it is today. That said, this would likely be a major change in the semantics of the API and would require a larger rework of filtering in JSONAPI.

Does this also happen in GraphQL?

clayreimann commented 6 years ago

The problem is we are unable to apply filtering the root and then not apply that same filter to children of the same type. This behavior does not occur in GraphQL because we don't use the request scope, so filters are defined on the collection where they should be applied.

I'm not convinced this is a major change in the semantics of the API, I'm more inclined to label this as a bug in our implementation of how we've defined filtering as it produces unintuitive and unexpected behavior. In any case, allowing targeted filters like filter[node.children]=... would be a non-invasive fix for the problem that would allow users to retain the current behavior (by not adding these new filter types) or get the behavior they want.