There is an OData feature which allows having a $filter
in a URL segment.
This feature is useful whenever there are operations on a collection and the client wants to perform those operations on a subset of the collection.
For example, the riskyUsers
API on Microsoft Graph has an action defined to let clients "dismiss" risky users (i.e. consider those users "not risky"):
<Action Name="dismiss" IsBound="true">
<Parameter Name="bindingParameter" Type="Collection(microsoft.graph.riskyUser)" />
<Parameter Name="userIds" Type="Collection(Edm.String)" />
</Action>
Using this action, clients can call
POST /identityProtection/riskyUsers/dismiss
{
"userIds": [
"{userId1}",
"{userId2}",
...
]
}
in order to dismiss the risky users with the provided IDs. Using the filter-as-segment OData feature, the action could instead be defined as:
<Action Name="dismiss" IsBound="true">
<Parameter Name="bindingParameter" Type="Collection(self.riskyUser)" />
</Action>
and clients could call
POST /identityProtection/riskyUsers/$filter=@f/dismiss?@f=id IN ('{userId1}','{userId2}',...)
Doing this is beneficial due to the robust nature of OData filter expressions: clients will be able to dismiss risky users based on any supported filter without the service team needing to implement a new dismiss
overload that filters based on the new criteria.
However, there are some concerns about the discoverability of using the filter-as-segment feature, as well as the support of parameter aliasing that's required.
As a result, functions should be introduced that act in the same way as the filter-as-segment:
<Function Name="filter" IsBound="true" IsComposable="true">
<Parameter Name="bindingParameter" Type="Collection(microsoft.graph.riskyUser)" Nullable="false" />
<Parameter Name="expression" Type="Edm.String" Nullable="false" />
<ReturnType Type="Collection(microsoft.graph.riskyUser)" />
</Function>
Clients would now be able to call
POST /identityProtection/riskyUsers/filter(expression='id IN (''{userId1}'',''{userId2}'',...)')/dismiss
NOTE: the '
literal in the filter expression must be escaped with ''
An example implementation of a filter function using OData WebApi can be found here.