From 92c7c95bf91587c05e4387d25ddf49489ac130a3 Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:06:09 -0800 Subject: [PATCH 1/6] Create filter-as-segment.md --- graph/articles/filter-as-segment.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 graph/articles/filter-as-segment.md diff --git a/graph/articles/filter-as-segment.md b/graph/articles/filter-as-segment.md new file mode 100644 index 00000000..b7819edd --- /dev/null +++ b/graph/articles/filter-as-segment.md @@ -0,0 +1,3 @@ +# Filter as segment + +There is an OData feature which allows From b7d11105781f479a11e9a64307bc618fcf6b99be Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:33:12 -0800 Subject: [PATCH 2/6] Update filter-as-segment.md --- graph/articles/filter-as-segment.md | 50 ++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/graph/articles/filter-as-segment.md b/graph/articles/filter-as-segment.md index b7819edd..91378b45 100644 --- a/graph/articles/filter-as-segment.md +++ b/graph/articles/filter-as-segment.md @@ -1,3 +1,51 @@ # Filter as segment -There is an OData feature which allows +There is an [OData feature](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_AddressingaSubsetofaCollection) 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"): + +```xml + + + + +``` + +Using this action, clients can call + +```http +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: + +```xml + + + +``` + +and clients could call: + +```http +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](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_ParameterAliases) that's required. +As a result, functions should be introduced that act in the same way as the filter-as-segment: + +```xml + + + + + +``` From b84171a78dbf5d4f18f0aa5ca71432117cd182af Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:35:42 -0800 Subject: [PATCH 3/6] Update filter-as-segment.md --- graph/articles/filter-as-segment.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/graph/articles/filter-as-segment.md b/graph/articles/filter-as-segment.md index 91378b45..b7da9841 100644 --- a/graph/articles/filter-as-segment.md +++ b/graph/articles/filter-as-segment.md @@ -6,7 +6,7 @@ For example, the `riskyUsers` API on Microsoft Graph has an action defined to le ```xml - + ``` @@ -32,10 +32,10 @@ in order to dismiss the risky users with the provided IDs. Using the filter-as-s ``` -and clients could call: +and clients could call ```http -POST /identityProtection/riskyUsers/$filter=@f/dismiss?@f=id IN ({userId1},{userId2},...) +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. @@ -43,9 +43,15 @@ However, there are some concerns about the discoverability of using the filter-a As a result, functions should be introduced that act in the same way as the filter-as-segment: ```xml - - + + - + ``` + +Clients would now be able to call + +```http +POST /identityProtection/riskyUsers/filter(expression='id IN (''{userId1}'',''{userId2}'',...)')/dismiss +``` From 651933d0e57fd17ed7569e46f065fb87b6470fa0 Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:37:02 -0800 Subject: [PATCH 4/6] Update filter-as-segment.md --- graph/articles/filter-as-segment.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/graph/articles/filter-as-segment.md b/graph/articles/filter-as-segment.md index b7da9841..56f81813 100644 --- a/graph/articles/filter-as-segment.md +++ b/graph/articles/filter-as-segment.md @@ -55,3 +55,7 @@ Clients would now be able to call ```http 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 can be found [here](TODO). From 9cec1749038df37e7ee034e6be26d444e9d5f824 Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:37:30 -0800 Subject: [PATCH 5/6] Update filter-as-segment.md --- graph/articles/filter-as-segment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph/articles/filter-as-segment.md b/graph/articles/filter-as-segment.md index 56f81813..6b067b01 100644 --- a/graph/articles/filter-as-segment.md +++ b/graph/articles/filter-as-segment.md @@ -58,4 +58,4 @@ POST /identityProtection/riskyUsers/filter(expression='id IN (''{userId1}'',''{u NOTE: the `'` literal in the filter expression must be escaped with `''` -An example implementation of a filter function can be found [here](TODO). +An example implementation of a filter function using OData WebApi can be found [here](TODO). From dc86042ff5d4834a16640fc3015dd22e6b2eaef8 Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:44:49 -0800 Subject: [PATCH 6/6] Update filter-as-segment.md --- graph/articles/filter-as-segment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph/articles/filter-as-segment.md b/graph/articles/filter-as-segment.md index 6b067b01..addaa0e0 100644 --- a/graph/articles/filter-as-segment.md +++ b/graph/articles/filter-as-segment.md @@ -58,4 +58,4 @@ POST /identityProtection/riskyUsers/filter(expression='id IN (''{userId1}'',''{u 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](TODO). +An example implementation of a filter function using OData WebApi can be found [here](https://github.com/OData/AspNetCoreOData/commit/7732f7e6b812d9a79a73529562f2e74b68e2794f).