From 8841d61310e3c9c4b41e845531121f15cd33b690 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 3 Jul 2024 12:17:58 -0700
Subject: [PATCH 01/22] Update collections.md
---
graph/articles/collections.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 6a24d9f0b..1172d8c07 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -316,3 +316,7 @@ Content-Type: application/json
"value": []
}
```
+
+## 11. Collections of structural types (complex types or primitive types)
+
+Collections of entity types are generally preferable to collections of structual types because collections of structural types must be updated as a single unit, meaning that they are overwritten entirely by new contents, rather than be updated relative to the existing contents.
From e7f42d8b31d48625696c05b9224f614b88e58a18 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 3 Jul 2024 12:33:42 -0700
Subject: [PATCH 02/22] Update collections.md
---
graph/articles/collections.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 1172d8c07..aec7e1b08 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -320,3 +320,9 @@ Content-Type: application/json
## 11. Collections of structural types (complex types or primitive types)
Collections of entity types are generally preferable to collections of structual types because collections of structural types must be updated as a single unit, meaning that they are overwritten entirely by new contents, rather than be updated relative to the existing contents.
+
+Sometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types. In these cases, there are two options forward:
+
+### 11.1 TODO side-by-side
+
+### 11.2 TODO $select trickery
From 3781028e0963e3b910a24778eb4ff2338bee049a Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 3 Jul 2024 12:38:07 -0700
Subject: [PATCH 03/22] Update collections.md
---
graph/articles/collections.md | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index aec7e1b08..4783797c3 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -325,4 +325,38 @@ Sometimes, structural collection properties are added to a type and then scenari
### 11.1 TODO side-by-side
+If there's an entity type `foo` that has a collection of `bar`s:
+
+```xml
+
+
+
+
+
+
+
+
+```
+and a scenario arises that requires, for example, to remove individual `bar`s from the collection, the model can be updated to have two collections side-by-side:
+
+```diff
+
+
++
+
+
+
+
+
+
+
++
++
++
++
++
++
++
+```
+
### 11.2 TODO $select trickery
From 6c2789b678270ed33b6aa2e2229c8f4c83ebaa42 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 3 Jul 2024 12:40:17 -0700
Subject: [PATCH 04/22] Update collections.md
---
graph/articles/collections.md | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 4783797c3..052b50196 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -329,6 +329,10 @@ If there's an entity type `foo` that has a collection of `bar`s:
```xml
+
+
+
+
@@ -338,9 +342,12 @@ If there's an entity type `foo` that has a collection of `bar`s:
```
and a scenario arises that requires, for example, to remove individual `bar`s from the collection, the model can be updated to have two collections side-by-side:
-
```diff
+
+
+
+
+
@@ -358,5 +365,11 @@ and a scenario arises that requires, for example, to remove individual `bar`s fr
+
+
```
+Clients will now be able to refer to individual `bar`s using `prop1` as a key, and they can now remove those `bar`s using `DELETE` requests:
+```http
+DELETE /foos/{fooId}/bars/{some_prop1}
+```
+```json
+```
### 11.2 TODO $select trickery
From e7edd544c8ef214fcb1fd6e258f01f378e893fb0 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 09:55:00 -0700
Subject: [PATCH 05/22] Update collections.md
---
graph/articles/collections.md | 90 ++++++++++++++++++++++++++++++++++-
1 file changed, 89 insertions(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 052b50196..45ef5a2df 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -369,7 +369,95 @@ Clients will now be able to refer to individual `bar`s using `prop1` as a key, a
```http
DELETE /foos/{fooId}/bars/{some_prop1}
```
-```json
+```http
+HTTP/1.1 204 No Content
+```
+The expectation is that `bars` and `barsAsEntities` are treated as two "views" into the same data.
+To meet this expectation, workloads must:
+1. Keep the properties consistent between `bar` and `barAsEntity`.
+Any changes to one type must be reflected in the other type.
+2. Reject requests that update both collections at the same time.
+A request that adds an item to `barsAsEntities` while replacing the content of `bars` must rejected with a `400`, for example:
+```http
+PATCH /foos/{fooId}
+{
+ "bars": [
+ {
+ "prop1": "some value",
+ "prop2": "another value"
+ }
+ ],
+ "barsAsEntities@delta": [
+ {
+ "prop1": "a key value",
+ "prop2": "some new value"
+ }
+ ]
+}
+```
+```http
+HTTP/1.1 400 Bad Request
+{
+ "error": {
+ "code": "badRequest",
+ "message": "'bars' and 'barsAsEntities' cannot be updated in the same request.",
+}
```
+TODO should this be a 409 conflict instead?
+TODO implement this in WebApi
+
### 11.2 TODO $select trickery
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 9b32887c882c5a3e6ff2573f8ccbccfc26fd72e3 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 09:55:24 -0700
Subject: [PATCH 06/22] Update collections.md
---
graph/articles/collections.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 45ef5a2df..cd00c070d 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -323,7 +323,7 @@ Collections of entity types are generally preferable to collections of structual
Sometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types. In these cases, there are two options forward:
-### 11.1 TODO side-by-side
+### 11.1 Side-by-side collection properties
If there's an entity type `foo` that has a collection of `bar`s:
From dd9fd4e448f05b1045c34cf23367d9c41cf8bb94 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 09:58:21 -0700
Subject: [PATCH 07/22] Update collections.md
---
graph/articles/collections.md | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index cd00c070d..80ee26540 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -320,12 +320,8 @@ Content-Type: application/json
## 11. Collections of structural types (complex types or primitive types)
Collections of entity types are generally preferable to collections of structual types because collections of structural types must be updated as a single unit, meaning that they are overwritten entirely by new contents, rather than be updated relative to the existing contents.
-
-Sometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types. In these cases, there are two options forward:
-
-### 11.1 Side-by-side collection properties
-
-If there's an entity type `foo` that has a collection of `bar`s:
+Sometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types.
+Take the following model with an entity type `foo` that has a collection of `bar`s:
```xml
@@ -341,7 +337,12 @@ If there's an entity type `foo` that has a collection of `bar`s:
```
-and a scenario arises that requires, for example, to remove individual `bar`s from the collection, the model can be updated to have two collections side-by-side:
+and a scenario arises that requires, for example, to remove individual `bar`s from the collection.
+There are two options forward:
+
+### 11.1 Side-by-side collection properties
+
+The model can be updated to have two collections side-by-side:
```diff
@@ -407,7 +408,7 @@ HTTP/1.1 400 Bad Request
TODO should this be a 409 conflict instead?
TODO implement this in WebApi
-### 11.2 TODO $select trickery
+### 11.2 `$select` overloading
From 2a0091fde9efae5453cec75b7f7a5955ff5e7dcf Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 10:01:32 -0700
Subject: [PATCH 08/22] Update collections.md
---
graph/articles/collections.md | 65 ++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 80ee26540..f7cc235a3 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -350,7 +350,7 @@ The model can be updated to have two collections side-by-side:
-+
++
@@ -410,6 +410,69 @@ TODO implement this in WebApi
### 11.2 `$select` overloading
+The model can be updated to simply switch the complex type for an entity type:
+```diff
+
+
+
+
+
+-
++
+
+
+-
++
++
++
++
+
+
+-
++
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 7823796fe4f337ec65a0c8d5eb92d062b3c21a9a Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 10:09:00 -0700
Subject: [PATCH 09/22] Update collections.md
---
graph/articles/collections.md | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index f7cc235a3..8948e3381 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -431,8 +431,31 @@ The model can be updated to simply switch the complex type for an entity type:
-
+
```
+To maintain backwards compatibility **and** compliance with the OData standard, there are several semantic changes that the workload must address:
+1. Existing clients would have been able to `$select` the `bars` property.
+Now that `bars` is a navigation property, the [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361040) specifies that its navigation link be returned when it is `$selected`:
+> If the select item is a navigation property, then the corresponding navigation link is represented in the response.
+Because the previous behavior for `$select=bars` was to include the collection in the response, and because the standard dictates that the navigation link be included in the response, the new behavior is to include both:
+
+```http
+GET /foos/{fooId}?$select=bars
+```
+```http
+200 OK
+{
+ "id": "{fooId}",
+ "bars": [
+ {
+ "prop1": "some value",
+ "prop2": "another value"
+ },
+ ...
+ ]
+ "bars@odata.navigationLink": "/foos('{fooId}')/bars"
+}
+```
From a59f82090e4608ec02209eefab849153f9582a5f Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 10:13:26 -0700
Subject: [PATCH 10/22] Update collections.md
---
graph/articles/collections.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 8948e3381..2c95438cc 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -457,6 +457,8 @@ GET /foos/{fooId}?$select=bars
}
```
+2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `foo` before, it must be preserved by **auto-expanding** the `bars` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).
+3. Structural collections are updated using `PATCH` requests to replace the entire contents of the collection. The new navigation property must preserve this behavior.
From 913775606b41e430cd8d140307ce34815496bbbb Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 5 Jul 2024 10:14:06 -0700
Subject: [PATCH 11/22] Update collections.md
---
graph/articles/collections.md | 93 +----------------------------------
1 file changed, 2 insertions(+), 91 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 2c95438cc..167e90b13 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -338,7 +338,7 @@ Take the following model with an entity type `foo` that has a collection of `bar
```
and a scenario arises that requires, for example, to remove individual `bar`s from the collection.
-There are two options forward:
+There are two options forward: //// TODO do we want to offer both options, or just one?
### 11.1 Side-by-side collection properties
@@ -460,93 +460,4 @@ GET /foos/{fooId}?$select=bars
2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `foo` before, it must be preserved by **auto-expanding** the `bars` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).
3. Structural collections are updated using `PATCH` requests to replace the entire contents of the collection. The new navigation property must preserve this behavior.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+TODO implement this in webapi
From d878b734cc8ab5fbe353f2a1c6db5bf52d57b7d0 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 13 Nov 2024 10:39:53 -0800
Subject: [PATCH 12/22] Update collections.md
---
graph/articles/collections.md | 99 ++++++++++++++++++-----------------
1 file changed, 51 insertions(+), 48 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 167e90b13..703819c76 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -321,77 +321,79 @@ Content-Type: application/json
Collections of entity types are generally preferable to collections of structual types because collections of structural types must be updated as a single unit, meaning that they are overwritten entirely by new contents, rather than be updated relative to the existing contents.
Sometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types.
-Take the following model with an entity type `foo` that has a collection of `bar`s:
+Take the following model with an entity type `application` that has a collection of `keyCredential`s:
```xml
-
+
-
+
+ ...
-
-
-
+
+
+
+ ...
```
-and a scenario arises that requires, for example, to remove individual `bar`s from the collection.
+and a scenario arises that requires, for example, to remove individual `keyCredential`s from the collection.
There are two options forward: //// TODO do we want to offer both options, or just one?
### 11.1 Side-by-side collection properties
The model can be updated to have two collections side-by-side:
```diff
-
+
-
-+
+
++
-
-
-
+
+
+
-+
++
+
-+
++
+
-+
-+
++
++
+
```
-Clients will now be able to refer to individual `bar`s using `prop1` as a key, and they can now remove those `bar`s using `DELETE` requests:
+Clients will now be able to refer to individual `keyCredential`s using `keyId` as a key, and they can now remove those `keyCredential`s using `DELETE` requests:
```http
-DELETE /foos/{fooId}/bars/{some_prop1}
+DELETE /applications/{applicationId}/keyCredentials/{some_keyId}
```
```http
HTTP/1.1 204 No Content
```
-The expectation is that `bars` and `barsAsEntities` are treated as two "views" into the same data.
+The expectation is that `keyCredentials` and `keyCredentialsAsEntities` are treated as two "views" into the same data.
To meet this expectation, workloads must:
-1. Keep the properties consistent between `bar` and `barAsEntity`.
+1. Keep the properties consistent between `keyCredential` and `keyCredentialAsEntity`.
Any changes to one type must be reflected in the other type.
2. Reject requests that update both collections at the same time.
-A request that adds an item to `barsAsEntities` while replacing the content of `bars` must rejected with a `400`, for example:
+A request that adds an item to `keyCredentialsAsEntities` while replacing the content of `keyCredentials` must rejected with a `400`, for example:
```http
-PATCH /foos/{fooId}
+PATCH /applications/{applicationId}
{
- "bars": [
+ "keyCredentials": [
{
- "prop1": "some value",
- "prop2": "another value"
+ "keyId": "10000000-0000-0000-0000-000000000000",
+ "endDateTime": "2012-12-03T07:16:23Z"
}
],
- "barsAsEntities@delta": [
+ "keyCredentialsAsEntities@delta": [
{
- "prop1": "a key value",
- "prop2": "some new value"
+ "keyId": "20000000-0000-0000-0000-000000000000",
+ "endDateTime": "2012-12-03T07:16:23Z"
}
]
}
@@ -401,7 +403,7 @@ HTTP/1.1 400 Bad Request
{
"error": {
"code": "badRequest",
- "message": "'bars' and 'barsAsEntities' cannot be updated in the same request.",
+ "message": "'keyCredentials' and 'keyCredentialsAsEntities' cannot be updated in the same request.",
}
```
@@ -412,52 +414,53 @@ TODO implement this in WebApi
The model can be updated to simply switch the complex type for an entity type:
```diff
-
+
--
-+
+-
++
--
-+
+-
++
+
-+
++
+
-
-
+
+
-
+
```
To maintain backwards compatibility **and** compliance with the OData standard, there are several semantic changes that the workload must address:
-1. Existing clients would have been able to `$select` the `bars` property.
-Now that `bars` is a navigation property, the [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361040) specifies that its navigation link be returned when it is `$selected`:
+1. Existing clients would have been able to `$select` the `keyCredentials` property.
+Now that `keyCredentials` is a navigation property, the [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361040) specifies that its navigation link be returned when it is `$selected`:
> If the select item is a navigation property, then the corresponding navigation link is represented in the response.
-Because the previous behavior for `$select=bars` was to include the collection in the response, and because the standard dictates that the navigation link be included in the response, the new behavior is to include both:
+Because the previous behavior for `$select=keyCredentials` was to include the collection in the response, and because the standard dictates that the navigation link be included in the response, the new behavior is to include both:
```http
-GET /foos/{fooId}?$select=bars
+GET /applications/{applicationId}?$select=keyCredentials
```
```http
200 OK
{
- "id": "{fooId}",
- "bars": [
+ "id": "{applicationId}",
+ "keyCredentials": [
{
- "prop1": "some value",
- "prop2": "another value"
+ "keyId": "30000000-0000-0000-0000-000000000000",
+ "endDateTime": "2012-12-03T07:16:23Z",
+ ...
},
...
]
- "bars@odata.navigationLink": "/foos('{fooId}')/bars"
+ "keyCredentials@odata.navigationLink": "/applications('{applicationId}')/keyCredentials"
}
```
-2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `foo` before, it must be preserved by **auto-expanding** the `bars` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).
+2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `application` before, it must be preserved by **auto-expanding** the `keyCredentials` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).
3. Structural collections are updated using `PATCH` requests to replace the entire contents of the collection. The new navigation property must preserve this behavior.
TODO implement this in webapi
From 0e22ae89319504e26592b8bf1301e90d3a69b2fb Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 13 Nov 2024 10:41:37 -0800
Subject: [PATCH 13/22] Update collections.md
---
graph/articles/collections.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 703819c76..aba35be95 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -48,7 +48,7 @@ GET https://graph.microsoft.com/beta/teamwork/devices/0f3ce432-e432-0f3c-32e4-3c
"value": {
"@odata.type": "#microsoft.graph.teamworkDevice",
"id": "0f3ce432-e432-0f3c-32e4-3c0f32e43c0f",
- "deviceType": "CollaborationBar",
+ "deviceType": "CollaborationBar",371
"hardwareDetail": {
"serialNumber": "0189",
"uniqueId": "5abcdefgh",
@@ -370,7 +370,7 @@ The model can be updated to have two collections side-by-side:
```
Clients will now be able to refer to individual `keyCredential`s using `keyId` as a key, and they can now remove those `keyCredential`s using `DELETE` requests:
```http
-DELETE /applications/{applicationId}/keyCredentials/{some_keyId}
+DELETE /applications/{applicationId}/keyCredentialsAsEntities/{some_keyId}
```
```http
HTTP/1.1 204 No Content
From 303804fb2411b241e4dd567ee1dc0a35fd8962a7 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 13 Nov 2024 10:42:33 -0800
Subject: [PATCH 14/22] Update graph/articles/collections.md
---
graph/articles/collections.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index aba35be95..a42b0abfa 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -455,7 +455,7 @@ GET /applications/{applicationId}?$select=keyCredentials
...
},
...
- ]
+ ],
"keyCredentials@odata.navigationLink": "/applications('{applicationId}')/keyCredentials"
}
```
From fa9198a505ca6960c4c9162055ba7e1ad48a79c8 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Thu, 14 Nov 2024 13:54:29 -0800
Subject: [PATCH 15/22] Update collections.md
---
graph/articles/collections.md | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index a42b0abfa..82458b947 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -351,7 +351,19 @@ The model can be updated to have two collections side-by-side:
-
+
++
++
++
++
++
++
++
++
++
++
++
++
+
From 560756b149dfebc758ef83b982d24e6caa2ddb8c Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Thu, 14 Nov 2024 13:55:22 -0800
Subject: [PATCH 16/22] Update collections.md
---
graph/articles/collections.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 82458b947..deabdcda2 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -344,7 +344,7 @@ There are two options forward: //// TODO do we want to offer both options, or ju
### 11.1 Side-by-side collection properties
-The model can be updated to have two collections side-by-side:
+The model can be updated to have two collections side-by-side, deprecating the existing one:
```diff
@@ -387,7 +387,7 @@ DELETE /applications/{applicationId}/keyCredentialsAsEntities/{some_keyId}
```http
HTTP/1.1 204 No Content
```
-The expectation is that `keyCredentials` and `keyCredentialsAsEntities` are treated as two "views" into the same data.
+While both properties exist on graph, the expectation is that `keyCredentials` and `keyCredentialsAsEntities` are treated as two "views" into the same data.
To meet this expectation, workloads must:
1. Keep the properties consistent between `keyCredential` and `keyCredentialAsEntity`.
Any changes to one type must be reflected in the other type.
From bb24f133213326bffcd6d03e7747b58e51937a3b Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Thu, 14 Nov 2024 13:55:48 -0800
Subject: [PATCH 17/22] Update collections.md
---
graph/articles/collections.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index deabdcda2..78e916566 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -48,7 +48,7 @@ GET https://graph.microsoft.com/beta/teamwork/devices/0f3ce432-e432-0f3c-32e4-3c
"value": {
"@odata.type": "#microsoft.graph.teamworkDevice",
"id": "0f3ce432-e432-0f3c-32e4-3c0f32e43c0f",
- "deviceType": "CollaborationBar",371
+ "deviceType": "CollaborationBar",
"hardwareDetail": {
"serialNumber": "0189",
"uniqueId": "5abcdefgh",
From 95063f934f3b83e46e3b123fff0c3fba48c7d474 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Thu, 14 Nov 2024 13:57:51 -0800
Subject: [PATCH 18/22] Update collections.md
---
graph/articles/collections.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 78e916566..6a87af976 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -342,7 +342,7 @@ Take the following model with an entity type `application` that has a collection
and a scenario arises that requires, for example, to remove individual `keyCredential`s from the collection.
There are two options forward: //// TODO do we want to offer both options, or just one?
-### 11.1 Side-by-side collection properties
+### 11.1 Side-by-side collection properties (for any collection of structural types)
The model can be updated to have two collections side-by-side, deprecating the existing one:
```diff
@@ -422,7 +422,7 @@ HTTP/1.1 400 Bad Request
TODO should this be a 409 conflict instead?
TODO implement this in WebApi
-### 11.2 `$select` overloading
+### 11.2 Redefine as Entity Type (for collections of complex types)
The model can be updated to simply switch the complex type for an entity type:
```diff
From cdcb0e383c0c62fdad441acd6fffdf58a18fbaef Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Thu, 14 Nov 2024 13:58:43 -0800
Subject: [PATCH 19/22] Update graph/articles/collections.md
Co-authored-by: Michael Pizzo
---
graph/articles/collections.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 6a87af976..cfd41b4b3 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -473,6 +473,6 @@ GET /applications/{applicationId}?$select=keyCredentials
```
2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `application` before, it must be preserved by **auto-expanding** the `keyCredentials` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).
-3. Structural collections are updated using `PATCH` requests to replace the entire contents of the collection. The new navigation property must preserve this behavior.
+3. Structural collections can be updated using a `PATCH` request to the containing entity to replace the entire contents of the collection. If the service supported such updates to the structural collection, then updates to the new navigation property must preserve this behavior.
TODO implement this in webapi
From 4d8039d5ad9a44c0d28a05850b2711f4786ccdd2 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Thu, 14 Nov 2024 13:58:57 -0800
Subject: [PATCH 20/22] Update graph/articles/collections.md
Co-authored-by: Michael Pizzo
---
graph/articles/collections.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index cfd41b4b3..6fba85663 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -319,7 +319,7 @@ Content-Type: application/json
## 11. Collections of structural types (complex types or primitive types)
-Collections of entity types are generally preferable to collections of structual types because collections of structural types must be updated as a single unit, meaning that they are overwritten entirely by new contents, rather than be updated relative to the existing contents.
+Entity types are generally preferred for collections since complex types within a collection cannot be individually referenced. Collections of complex types, including any nested properties, must be updated as a single unit, entirely replacing the existing contents. Even if your API is read-only today, modeling it as a collection of entities gives you more flexibility in referencing individual members now and in the future.
Sometimes, structural collection properties are added to a type and then scenarios are discovered later that require a collection of entity types.
Take the following model with an entity type `application` that has a collection of `keyCredential`s:
From 114fe124bb568a84bee4c5d2e2b86540ac205e4c Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Mon, 18 Nov 2024 16:01:16 -0800
Subject: [PATCH 21/22] Update collections.md
---
graph/articles/collections.md | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index 6fba85663..b96f4b6c6 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -340,7 +340,7 @@ Take the following model with an entity type `application` that has a collection
```
and a scenario arises that requires, for example, to remove individual `keyCredential`s from the collection.
-There are two options forward: //// TODO do we want to offer both options, or just one?
+There are two options forward:
### 11.1 Side-by-side collection properties (for any collection of structural types)
@@ -419,9 +419,6 @@ HTTP/1.1 400 Bad Request
}
```
-TODO should this be a 409 conflict instead?
-TODO implement this in WebApi
-
### 11.2 Redefine as Entity Type (for collections of complex types)
The model can be updated to simply switch the complex type for an entity type:
@@ -474,5 +471,3 @@ GET /applications/{applicationId}?$select=keyCredentials
2. The default behavior for structural collections is to include them in the response payload for their containing entity. If this was the behavior of `application` before, it must be preserved by **auto-expanding** the `keyCredentials` property now that it is a navigation property (because the default behavior for navigation properties is to **not** expand them).
3. Structural collections can be updated using a `PATCH` request to the containing entity to replace the entire contents of the collection. If the service supported such updates to the structural collection, then updates to the new navigation property must preserve this behavior.
-
-TODO implement this in webapi
From f0fdbd5ad97717ff86751cf7222a65616bf383ab Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Wed, 4 Dec 2024 10:05:28 -0800
Subject: [PATCH 22/22] Update collections.md
---
graph/articles/collections.md | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/graph/articles/collections.md b/graph/articles/collections.md
index b96f4b6c6..00276dbd1 100644
--- a/graph/articles/collections.md
+++ b/graph/articles/collections.md
@@ -358,13 +358,13 @@ The model can be updated to have two collections side-by-side, deprecating the e
+
+
+
-+
++
+
+
+
+
+
-+
++
@@ -372,7 +372,7 @@ The model can be updated to have two collections side-by-side, deprecating the e
-+
++
+
+
+
@@ -382,17 +382,17 @@ The model can be updated to have two collections side-by-side, deprecating the e
```
Clients will now be able to refer to individual `keyCredential`s using `keyId` as a key, and they can now remove those `keyCredential`s using `DELETE` requests:
```http
-DELETE /applications/{applicationId}/keyCredentialsAsEntities/{some_keyId}
+DELETE /applications/{applicationId}/keyCredentials_v2/{some_keyId}
```
```http
HTTP/1.1 204 No Content
```
-While both properties exist on graph, the expectation is that `keyCredentials` and `keyCredentialsAsEntities` are treated as two "views" into the same data.
+While both properties exist on graph, the expectation is that `keyCredentials` and `keyCredentials_v2` are treated as two "views" into the same data.
To meet this expectation, workloads must:
-1. Keep the properties consistent between `keyCredential` and `keyCredentialAsEntity`.
+1. Keep the properties consistent between `keyCredential` and `keyCredential_v2`.
Any changes to one type must be reflected in the other type.
2. Reject requests that update both collections at the same time.
-A request that adds an item to `keyCredentialsAsEntities` while replacing the content of `keyCredentials` must rejected with a `400`, for example:
+A request that adds an item to `keyCredentials_v2` while replacing the content of `keyCredentials` must rejected with a `400`, for example:
```http
PATCH /applications/{applicationId}
{
@@ -402,7 +402,7 @@ PATCH /applications/{applicationId}
"endDateTime": "2012-12-03T07:16:23Z"
}
],
- "keyCredentialsAsEntities@delta": [
+ "keyCredentials_v2@delta": [
{
"keyId": "20000000-0000-0000-0000-000000000000",
"endDateTime": "2012-12-03T07:16:23Z"
@@ -415,7 +415,7 @@ HTTP/1.1 400 Bad Request
{
"error": {
"code": "badRequest",
- "message": "'keyCredentials' and 'keyCredentialsAsEntities' cannot be updated in the same request.",
+ "message": "'keyCredentials' and 'keyCredentials_v2' cannot be updated in the same request.",
}
```