From eed371b3eda200c48573eb9bc6f7ae4fc0aa6ce0 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:31:12 -0700
Subject: [PATCH 01/24] Update GuidelinesGraph.md
---
graph/GuidelinesGraph.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/graph/GuidelinesGraph.md b/graph/GuidelinesGraph.md
index e0fecabd..2b7b800d 100644
--- a/graph/GuidelinesGraph.md
+++ b/graph/GuidelinesGraph.md
@@ -182,7 +182,9 @@ Another way to avoid this is to use JSON batch as described in the [Microsoft Gr
You can model structured resources for your APIs by using the OData entity type or complex type. The main difference between these types is that an entity type declares a key property to uniquely identify its objects, and a complex type does not. In Microsoft Graph, this key property is called `id` for server-created key values. If there is a natural name for the key property, then the workload can use that.
-Because objects of complex types in Microsoft Graph don’t have unique identifiers, they are not directly addressable via URIs. Therefore, you must use entity types to model addressable resources such as individually addressable items within a collection. For more information, see the [Microsoft REST API Guidelines collection URL patterns](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#93-collection-url-patterns). Complex types are better suited to represent composite properties of API entities.
+Because objects of complex types in Microsoft Graph don’t have unique identifiers, they are not directly addressable via URIs. Therefore, you must use entity types to model addressable resources such as individually addressable items within a collection. For more information, see the [Microsoft REST API Guidelines collection URL patterns](https://github.com/microsoft/api-guidelines/blob/vNext/Guidelines.md#93-collection-url-patterns).
+This is also why [collection properties](./collection-properties.md) should almost always be modeled using an entity type rather than a complex type.
+Complex types are better suited to represent composite properties of API entities.
```xml
From 5530b27fc191c8b58168e626ceaebff8908510bc Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:33:53 -0700
Subject: [PATCH 02/24] Create collection-properties.md
---
graph/collection-properties.md | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 graph/collection-properties.md
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
new file mode 100644
index 00000000..b2c36153
--- /dev/null
+++ b/graph/collection-properties.md
@@ -0,0 +1,2 @@
+OData services treat collections of complex types differently than they treat collections of entity types.
+This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
From 560f7bc18cb6fe7c35179b8c1f5ea85d6a44e9f2 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:47:57 -0700
Subject: [PATCH 03/24] Update collection-properties.md
---
graph/collection-properties.md | 67 ++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index b2c36153..ef9d9b97 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -1,2 +1,69 @@
OData services treat collections of complex types differently than they treat collections of entity types.
This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
+Let's use the following CSDL as an example:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## Adding elements to a collection
+
+For both `foos` and `bars`, the OData standard specifies that elements can be added to the collection using a `POST` request
+1. [Complex Types](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateaCollectionProperty):
+
+ > A successful POST request to the edit URL of a collection property adds an item to the collection.
+2. [Entity Types](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358976)
+
+ > To create an entity in a collection, the client sends a POST request to that collection's URL.
+
+### Complex Type
+
+```HTTP
+POST /interestingData/foos
+{
+ "someProperty": "a value"
+}
+
+200 OK
+{
+ "value": [
+ {
+ "someProperty": "a value"
+ }
+ ]
+}
+```
+
+### Entity Type
+
+```HTTP
+POST /interestingData/bars
+{
+ "differentProperty": 42
+}
+
+200 OK
+{
+ "value": [
+ {
+ "id": "firstBarId",
+ "differentProperty": 42
+ }
+ ]
+}
+```
From e1bd65006a8091640fa30b945731197b871bc618 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:50:22 -0700
Subject: [PATCH 04/24] Update collection-properties.md
---
graph/collection-properties.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index ef9d9b97..d5a61504 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -1,5 +1,6 @@
OData services treat collections of complex types differently than they treat collections of entity types.
This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
+The result of these differences is that it is almost always preferable to use entity types for collections rather than complex types; please see the exceptions [here](TODO).
Let's use the following CSDL as an example:
```xml
@@ -67,3 +68,5 @@ POST /interestingData/bars
]
}
```
+
+## Retrieving elements from a collection
From 737f183a933857b555728b57086cb6b104536e89 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:58:42 -0700
Subject: [PATCH 05/24] Update collection-properties.md
---
graph/collection-properties.md | 39 +++++++++++++++++++++++++++++-----
1 file changed, 34 insertions(+), 5 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index d5a61504..0737d460 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -40,6 +40,35 @@ POST /interestingData/foos
"someProperty": "a value"
}
+204 No Content
+```
+
+### Entity Type
+
+```HTTP
+POST /interestingData/bars
+{
+ "differentProperty": 42
+}
+
+204 No Content
+Location: /interestingData/bars/firstBarId
+```
+
+## Retrieving the elements in a collection
+
+The [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358935) [standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358947) also allows `foos` and `bars` both to be retrieved using a `GET` request:
+> OData services support requests for data via HTTP GET requests.
+>
+> ...
+>
+> OData services support querying collections of entities, complex type instances, and primitive values.
+
+### Complex Type
+
+```HTTP
+GET /interestingData/foos
+
200 OK
{
"value": [
@@ -53,10 +82,7 @@ POST /interestingData/foos
### Entity Type
```HTTP
-POST /interestingData/bars
-{
- "differentProperty": 42
-}
+GET /interestingData/bars
200 OK
{
@@ -69,4 +95,7 @@ POST /interestingData/bars
}
```
-## Retrieving elements from a collection
+## Retrieving individual elements from a collection
+
+TODOD
+https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_RequestingIndividualEntities
From 2ad5cf64ecf207c9f1e971d39dcc54a551ab6881 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 16:01:24 -0700
Subject: [PATCH 06/24] Update collection-properties.md
---
graph/collection-properties.md | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 0737d460..64f90bb0 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -97,5 +97,19 @@ GET /interestingData/bars
## Retrieving individual elements from a collection
-TODOD
-https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_RequestingIndividualEntities
+The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_RequestingIndividualEntities) also specifies that clients can retrieve individual elements of a collection of entity types:
+> To retrieve an individual entity, the client makes a GET request to a URL that identifies the entity, e.g. its read URL.
+
+However, there is no way to do this for complex types because there is not way to identity a particular instance of a complex type.
+
+### Entity Type
+
+```HTTP
+GET /interestingData/bars/firstBarId
+
+200 OK
+{
+ "id": "firstBarId",
+ "differentProperty": 42
+}
+```
From 266cc13f381c65b7cd2e73de539b74bd46c40150 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 16:08:34 -0700
Subject: [PATCH 07/24] Update collection-properties.md
---
graph/collection-properties.md | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 64f90bb0..87441a27 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -22,7 +22,7 @@ Let's use the following CSDL as an example:
```
-## Adding elements to a collection
+## Adding individual elements to a collection
For both `foos` and `bars`, the OData standard specifies that elements can be added to the collection using a `POST` request
1. [Complex Types](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateaCollectionProperty):
@@ -113,3 +113,31 @@ GET /interestingData/bars/firstBarId
"differentProperty": 42
}
```
+
+## Removing individual elements from a collection
+
+TODO
+
+## Updating individual elements in a collection
+
+TODO
+
+## Updating a collection
+
+TODO do PATCH for complex type and POST + PATCH for entity types
+
+## Exceptions
+
+TODO
+
+## Conclusion
+
+Collections of entity types have several behaviors that are not available for collections of complex types:
+1. Individual elements can be retrieved
+2. Individual elements can be removed
+3. Individual elements can be updated
+4. Several elements within the collection may be added, removed, or updated in a single request
+
+Further, to remove or update elements in a collection of complex types, the entire collection must be replace with a `PATCH` request.
+This has the potential to result in data loss for clients who accidentally don't include all of the current elements of the collection, or encounter a race condition where two clients are attempting to `PATCH` the same collection.
+Due to the increased flexiblity of collections of entity types, and the data loss risks for collections of complex types, collections of entity types should be used.
From 8678289262b37c65960ca1cc85b027537ae882d3 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 16:09:11 -0700
Subject: [PATCH 08/24] Update collection-properties.md
---
graph/collection-properties.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 87441a27..b1fb06cd 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -7,6 +7,7 @@ Let's use the following CSDL as an example:
+
From d0666a74d29fe1caaa16b999bf2bf0f2f232dea2 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 16:16:12 -0700
Subject: [PATCH 09/24] Update collection-properties.md
---
graph/collection-properties.md | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index b1fb06cd..3c3ea90e 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -53,12 +53,12 @@ POST /interestingData/bars
}
204 No Content
-Location: /interestingData/bars/firstBarId
+Location: /interestingData/bars/thirdBarId
```
## Retrieving the elements in a collection
-The [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358935) [standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358947) also allows `foos` and `bars` both to be retrieved using a `GET` request:
+The [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358935) [standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358947) specifies `foos` and `bars` both can be retrieved using a `GET` request:
> OData services support requests for data via HTTP GET requests.
>
> ...
@@ -73,6 +73,9 @@ GET /interestingData/foos
200 OK
{
"value": [
+ {
+ "someProperty": "an original value"
+ },
{
"someProperty": "a value"
}
@@ -90,6 +93,14 @@ GET /interestingData/bars
"value": [
{
"id": "firstBarId",
+ "differentProperty": 10
+ },
+ {
+ "id": "secondBarId",
+ "differentProperty": -6914
+ }
+ {
+ "id": "thirdBarId",
"differentProperty": 42
}
]
@@ -98,10 +109,10 @@ GET /interestingData/bars
## Retrieving individual elements from a collection
-The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_RequestingIndividualEntities) also specifies that clients can retrieve individual elements of a collection of entity types:
+The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_RequestingIndividualEntities) specifies that clients can retrieve individual elements of a collection of entity types using a `GET` request:
> To retrieve an individual entity, the client makes a GET request to a URL that identifies the entity, e.g. its read URL.
-However, there is no way to do this for complex types because there is not way to identity a particular instance of a complex type.
+There is no way to do this for complex types because there is no way to identity a particular instance of a complex type within a collection.
### Entity Type
@@ -117,7 +128,18 @@ GET /interestingData/bars/firstBarId
## Removing individual elements from a collection
-TODO
+The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_DeleteanEntity) specifies that clients can remove individual elements of a collection of entity types using a `DELETE` request:
+> To delete an individual entity, the client makes a DELETE request to a URL that identifies the entity.
+
+There is no way to do this for complex types because there is no way to identity a particular instance of a complex type within a collection.
+
+### Entity Type
+
+```HTTP
+DELETE /interestingData/bars/firstBarId
+
+204 No Content
+```
## Updating individual elements in a collection
From b86e8e2e141e1d49f8ff69f536eb51bd6b10dc8d Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 16:16:46 -0700
Subject: [PATCH 10/24] Update collection-properties.md
---
graph/collection-properties.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 3c3ea90e..5abe52bd 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -136,7 +136,7 @@ There is no way to do this for complex types because there is no way to identity
### Entity Type
```HTTP
-DELETE /interestingData/bars/firstBarId
+DELETE /interestingData/bars/thirdBarId
204 No Content
```
From f69898e057f124e7a23983855c35eaedb95f1b05 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 14 Jul 2023 17:25:52 -0700
Subject: [PATCH 11/24] Update collection-properties.md
---
graph/collection-properties.md | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 5abe52bd..1a4496cb 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -143,7 +143,21 @@ DELETE /interestingData/bars/thirdBarId
## Updating individual elements in a collection
-TODO
+The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) specifies that clients can update individual elements of a collection of entity types using a `PATCH` request:
+> To update an individual entity, the client makes a PATCH or PUT request to a URL that identifies the entity.
+
+There is no way to do this for complex types because there is no way to identity a particular instance of a complex type within a collection.
+
+### Entity Type
+
+```HTTP
+PATCH /interestingData/bars/firstBarId
+{
+ "differentProperty": "15"
+}
+
+204 No Content
+```
## Updating a collection
From 01e645d6d4aeb9be7a8ccdc0bdb92dc98073bcb2 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 07:41:02 -0700
Subject: [PATCH 12/24] Update collection-properties.md
---
graph/collection-properties.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 1a4496cb..a9479bbe 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -112,7 +112,7 @@ GET /interestingData/bars
The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_RequestingIndividualEntities) specifies that clients can retrieve individual elements of a collection of entity types using a `GET` request:
> To retrieve an individual entity, the client makes a GET request to a URL that identifies the entity, e.g. its read URL.
-There is no way to do this for complex types because there is no way to identity a particular instance of a complex type within a collection.
+There is no way to do this for complex types because there is no way to address a particular instance of a complex type within a collection.
### Entity Type
@@ -131,7 +131,7 @@ GET /interestingData/bars/firstBarId
The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_DeleteanEntity) specifies that clients can remove individual elements of a collection of entity types using a `DELETE` request:
> To delete an individual entity, the client makes a DELETE request to a URL that identifies the entity.
-There is no way to do this for complex types because there is no way to identity a particular instance of a complex type within a collection.
+There is no way to do this for complex types because there is no way to address a particular instance of a complex type within a collection.
### Entity Type
@@ -146,7 +146,7 @@ DELETE /interestingData/bars/thirdBarId
The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) specifies that clients can update individual elements of a collection of entity types using a `PATCH` request:
> To update an individual entity, the client makes a PATCH or PUT request to a URL that identifies the entity.
-There is no way to do this for complex types because there is no way to identity a particular instance of a complex type within a collection.
+There is no way to do this for complex types because there is no way to address a particular instance of a complex type within a collection.
### Entity Type
@@ -175,6 +175,6 @@ Collections of entity types have several behaviors that are not available for co
3. Individual elements can be updated
4. Several elements within the collection may be added, removed, or updated in a single request
-Further, to remove or update elements in a collection of complex types, the entire collection must be replace with a `PATCH` request.
+Further, to remove or update elements in a collection of complex types, the entire collection must be replaced with a `PATCH` request.
This has the potential to result in data loss for clients who accidentally don't include all of the current elements of the collection, or encounter a race condition where two clients are attempting to `PATCH` the same collection.
Due to the increased flexiblity of collections of entity types, and the data loss risks for collections of complex types, collections of entity types should be used.
From dd9ce6899857bd630a05d79072dfed3d54b73432 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 07:41:56 -0700
Subject: [PATCH 13/24] Update collection-properties.md
---
graph/collection-properties.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index a9479bbe..6cff60f7 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -1,6 +1,6 @@
OData services treat collections of complex types differently than they treat collections of entity types.
This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
-The result of these differences is that it is almost always preferable to use entity types for collections rather than complex types; please see the exceptions [here](TODO).
+The result of these differences is that it is almost always preferable to use entity types for collections rather than complex types; please see the exceptions [here](#exceptions).
Let's use the following CSDL as an example:
```xml
From d530eaaec4134932a2299c960b4f80dcd17b8fb3 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 07:48:28 -0700
Subject: [PATCH 14/24] Update collection-properties.md
---
graph/collection-properties.md | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 6cff60f7..6888336c 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -160,8 +160,12 @@ PATCH /interestingData/bars/firstBarId
```
## Updating a collection
+/*
+https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity
+The semantics of PATCH, as defined in [RFC5789], is to merge the content in the request payload with the [entity’s] current state, applying the update only to those components specified in the request body. Collection properties and primitive properties provided in the payload corresponding to updatable properties MUST replace the value of the corresponding property in the entity or complex type. Missing properties of the containing entity or complex property, including dynamic properties, MUST NOT be directly altered unless as a side effect of changes resulting from the provided properties.
+*/
-TODO do PATCH for complex type and POST + PATCH for entity types
+TODO do PATCH for complex type and POST overwrite + delta PATCH for entity types
## Exceptions
From e44c3606e3f43b9f835c261fd47e34c23a2ddcfb Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:12:45 -0700
Subject: [PATCH 15/24] Update collection-properties.md
---
graph/collection-properties.md | 216 ++++++++++++++++++++++++++++-----
1 file changed, 188 insertions(+), 28 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 6888336c..913701d7 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -23,6 +23,50 @@ Let's use the following CSDL as an example:
```
+## Retrieving the elements in a collection
+
+The [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358935) [standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358947) specifies `foos` and `bars` both can be retrieved using a `GET` request:
+> OData services support requests for data via HTTP GET requests.
+>
+> ...
+>
+> OData services support querying collections of entities, complex type instances, and primitive values.
+
+### Complex Type
+
+```HTTP
+GET /interestingData/foos
+
+200 OK
+{
+ "value": [
+ {
+ "someProperty": "an original value"
+ }
+ ]
+}
+```
+
+### Entity Type
+
+```HTTP
+GET /interestingData/bars
+
+200 OK
+{
+ "value": [
+ {
+ "id": "firstBarId",
+ "differentProperty": 10
+ },
+ {
+ "id": "secondBarId",
+ "differentProperty": -6914
+ }
+ ]
+}
+```
+
## Adding individual elements to a collection
For both `foos` and `bars`, the OData standard specifies that elements can be added to the collection using a `POST` request
@@ -35,6 +79,8 @@ For both `foos` and `bars`, the OData standard specifies that elements can be ad
### Complex Type
+#### Add an element to the collection
+
```HTTP
POST /interestingData/foos
{
@@ -44,28 +90,7 @@ POST /interestingData/foos
204 No Content
```
-### Entity Type
-
-```HTTP
-POST /interestingData/bars
-{
- "differentProperty": 42
-}
-
-204 No Content
-Location: /interestingData/bars/thirdBarId
-```
-
-## Retrieving the elements in a collection
-
-The [OData](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358935) [standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#_Toc31358947) specifies `foos` and `bars` both can be retrieved using a `GET` request:
-> OData services support requests for data via HTTP GET requests.
->
-> ...
->
-> OData services support querying collections of entities, complex type instances, and primitive values.
-
-### Complex Type
+#### Check the new contents of the collection
```HTTP
GET /interestingData/foos
@@ -85,6 +110,20 @@ GET /interestingData/foos
### Entity Type
+#### Add an element to the collection
+
+```HTTP
+POST /interestingData/bars
+{
+ "differentProperty": 42
+}
+
+204 No Content
+Location: /interestingData/bars/thirdBarId
+```
+
+#### Check the new contents of the collection
+
```HTTP
GET /interestingData/bars
@@ -98,7 +137,7 @@ GET /interestingData/bars
{
"id": "secondBarId",
"differentProperty": -6914
- }
+ },
{
"id": "thirdBarId",
"differentProperty": 42
@@ -135,12 +174,34 @@ There is no way to do this for complex types because there is no way to address
### Entity Type
+#### Remove an element from the collection
+
```HTTP
DELETE /interestingData/bars/thirdBarId
204 No Content
```
+#### Check the new contents of the collection
+
+```HTTP
+GET /interestingData/bars
+
+200 OK
+{
+ "value": [
+ {
+ "id": "firstBarId",
+ "differentProperty": 10
+ },
+ {
+ "id": "secondBarId",
+ "differentProperty": -6914
+ }
+ ]
+}
+```
+
## Updating individual elements in a collection
The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) specifies that clients can update individual elements of a collection of entity types using a `PATCH` request:
@@ -150,6 +211,8 @@ There is no way to do this for complex types because there is no way to address
### Entity Type
+#### Update an element in the collection
+
```HTTP
PATCH /interestingData/bars/firstBarId
{
@@ -159,13 +222,110 @@ PATCH /interestingData/bars/firstBarId
204 No Content
```
+#### Check the new contents of the collection
+
+```HTTP
+GET /interestingData/bars
+
+200 OK
+{
+ "value": [
+ {
+ "id": "firstBarId",
+ "differentProperty": 15
+ },
+ {
+ "id": "secondBarId",
+ "differentProperty": -6914
+ }
+ ]
+}
+```
+
## Updating a collection
-/*
-https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity
-The semantics of PATCH, as defined in [RFC5789], is to merge the content in the request payload with the [entity’s] current state, applying the update only to those components specified in the request body. Collection properties and primitive properties provided in the payload corresponding to updatable properties MUST replace the value of the corresponding property in the entity or complex type. Missing properties of the containing entity or complex property, including dynamic properties, MUST NOT be directly altered unless as a side effect of changes resulting from the provided properties.
-*/
-TODO do PATCH for complex type and POST overwrite + delta PATCH for entity types
+The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) specifies that clients can replace all elements of a collection of complex types or all elements of a collection of entity types using a `PATCH` request:
+> Collection properties...provided in the payload corresponding to updatable properties MUST replace the value of the corresponding property in the entity or complex type.
+
+TODO the dstandard also blah blah delta path blah
+
+### Complex Type
+
+#### Replace the elements in a collection
+
+```HTTP
+PATCH /interestingData
+{
+ "foos": [
+ {
+ "someProperty": "a replacement value"
+ },
+ {
+ "someProperty": "more replacement value"
+ },
+ {
+ "someProperty": "a new value demonstrating that additional elements can be in the collection"
+ }
+ ]
+}
+
+204 No Content
+```
+
+#### Check the new contents of the collection
+
+```HTTP
+GET /interestingData/foos
+
+200 OK
+{
+ "value": [
+ {
+ "someProperty": "a replacement value"
+ },
+ {
+ "someProperty": "more replacement value"
+ },
+ {
+ "someProperty": "a new value demonstrating that additional elements can be in the collection"
+ }
+ ]
+}
+```
+
+### Entity Type
+
+#### Replace the elements in a collection
+
+```HTTP
+PATCH /interestingData
+{
+ "bars": [
+ {
+ "id": "fourthBarId",
+ "differentProperty": 20
+ }
+ ]
+}
+
+204 No Content
+```
+
+#### Check the new contents of the collection
+
+```HTTP
+GET /interestingData/bars
+
+200 OK
+{
+ "value": [
+ {
+ "id": "fourthBarId",
+ "differentProperty": 20
+ }
+ ]
+}
+```
## Exceptions
From 432a2d96f72de39283169491572f9d16da4d8145 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:20:13 -0700
Subject: [PATCH 16/24] Update collection-properties.md
---
graph/collection-properties.md | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 913701d7..2647df5d 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -247,6 +247,9 @@ GET /interestingData/bars
The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_UpdateanEntity) specifies that clients can replace all elements of a collection of complex types or all elements of a collection of entity types using a `PATCH` request:
> Collection properties...provided in the payload corresponding to updatable properties MUST replace the value of the corresponding property in the entity or complex type.
+The standard also specifies that collections of entities can be updated in a relative fashion using the [delta syntax](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#_Toc38457777) in a `PATCH` request:
+> The body of a PATCH request to a URL identifying a collection of entities...MUST contain the context control information...and...MUST contain an array-valued property named value containing all added, changed, or deleted entities...
+
TODO the dstandard also blah blah delta path blah
### Complex Type
@@ -327,6 +330,14 @@ GET /interestingData/bars
}
```
+#### Change the elements in a collection
+
+TODO
+
+#### Check the new contents of the collection
+
+TODO
+
## Exceptions
TODO
From c187356f7783ac33af38f64d60edf83bb83618db Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:20:44 -0700
Subject: [PATCH 17/24] Update collection-properties.md
---
graph/collection-properties.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 2647df5d..e903a04b 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -325,6 +325,10 @@ GET /interestingData/bars
{
"id": "fourthBarId",
"differentProperty": 20
+ },
+ {
+ "id": "fifthBarId",
+ "differentProperty": -99999
}
]
}
From f3313c61ecbc5110405122162333838ffc0abbbd Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:24:14 -0700
Subject: [PATCH 18/24] Update collection-properties.md
---
graph/collection-properties.md | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index e903a04b..72d1348b 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -336,7 +336,26 @@ GET /interestingData/bars
#### Change the elements in a collection
-TODO
+```HTTP
+PATCH /interestingData/bars
+{
+ "@context": "#$delta",
+ "value": [
+ {
+ "id": "fifthBarId",
+ "differentProperty": 1024
+ },
+ {
+ "id": "sixthBarId",
+ "differentProperty": 9801
+ },
+ {
+ "id": "fourthBarId",
+ "@removed": {}
+ }
+ ]
+}
+```
#### Check the new contents of the collection
From 3dc8cb8dada18470ae5475aa39a8cfe60b40c342 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:25:17 -0700
Subject: [PATCH 19/24] Update collection-properties.md
---
graph/collection-properties.md | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 72d1348b..30db2c68 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -355,11 +355,29 @@ PATCH /interestingData/bars
}
]
}
+
+204 No Content
```
#### Check the new contents of the collection
-TODO
+```HTTP
+GET /interestingData/bars
+
+200 OK
+{
+ "value": [
+ {
+ "id": "fifthBarId",
+ "differentProperty": 1024
+ },
+ {
+ "id": "sixthBarId",
+ "differentProperty": 9801
+ }
+ ]
+}
+```
## Exceptions
From 0871308a27a75f60d4bd7be974a518399bbdc172 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:25:37 -0700
Subject: [PATCH 20/24] Update collection-properties.md
---
graph/collection-properties.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 30db2c68..48d7f099 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -250,8 +250,6 @@ The [OData standard](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-p
The standard also specifies that collections of entities can be updated in a relative fashion using the [delta syntax](https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#_Toc38457777) in a `PATCH` request:
> The body of a PATCH request to a URL identifying a collection of entities...MUST contain the context control information...and...MUST contain an array-valued property named value containing all added, changed, or deleted entities...
-TODO the dstandard also blah blah delta path blah
-
### Complex Type
#### Replace the elements in a collection
From 08e0f655b6075a9df901f1bb5f9425623a79bc53 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:30:51 -0700
Subject: [PATCH 21/24] Update collection-properties.md
---
graph/collection-properties.md | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 48d7f099..b26adc33 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -7,7 +7,6 @@ Let's use the following CSDL as an example:
-
@@ -379,7 +378,12 @@ GET /interestingData/bars
## Exceptions
-TODO
+It might not make sense for a collection property to be a collection of entities in cases where the collection must be viewed holistically; that is, cases where one element in the collection impacts or is coupled with another element in the collection.
+The most common example of this would be a list of "tasks" that should be executed in order.
+Inserting a single task into a collection only makes sense because the client knows the preceeding and proceeding tasks.
+In cases like this, it might make sense for a collection to use a complex type instead of an entity type.
+However, even in this case, it might make sense to use a collection of entity types anyway so that clients can individually address the tasks in the list, having URLs to individual tasks that can be referred to.
+In such a case, the delta `PATCH` request on this collection would simply be not supported.
## Conclusion
From d915adf4b79fef7b81065b982a415d2603152399 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Fri, 21 Jul 2023 08:44:27 -0700
Subject: [PATCH 22/24] Update collection-properties.md
---
graph/collection-properties.md | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index b26adc33..6440a6f0 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -1,6 +1,6 @@
OData services treat collections of complex types differently than they treat collections of entity types.
This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
-The result of these differences is that it is almost always preferable to use entity types for collections rather than complex types; please see the exceptions [here](#exceptions).
+The result of this difference is that it is almost always preferable to use entity types for collections rather than complex types; please see the exceptions [here](#exceptions).
Let's use the following CSDL as an example:
```xml
@@ -160,7 +160,7 @@ GET /interestingData/bars/firstBarId
200 OK
{
"id": "firstBarId",
- "differentProperty": 42
+ "differentProperty": 10
}
```
@@ -304,6 +304,10 @@ PATCH /interestingData
{
"id": "fourthBarId",
"differentProperty": 20
+ },
+ {
+ "id": "fifthBarId",
+ "differentProperty": -99999
}
]
}
@@ -383,7 +387,7 @@ The most common example of this would be a list of "tasks" that should be execut
Inserting a single task into a collection only makes sense because the client knows the preceeding and proceeding tasks.
In cases like this, it might make sense for a collection to use a complex type instead of an entity type.
However, even in this case, it might make sense to use a collection of entity types anyway so that clients can individually address the tasks in the list, having URLs to individual tasks that can be referred to.
-In such a case, the delta `PATCH` request on this collection would simply be not supported.
+In such a case, the workload should simply not support a delta `PATCH` request on this collection.
## Conclusion
From a16c2f7f67475573609b63d8035e17275127724f Mon Sep 17 00:00:00 2001
From: OlgaPodo <86168392+OlgaPodo@users.noreply.github.com>
Date: Fri, 1 Dec 2023 11:25:50 -0500
Subject: [PATCH 23/24] Update graph/collection-properties.md
Co-authored-by: Dan Kershaw [MSFT]
---
graph/collection-properties.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 6440a6f0..59f605a2 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -1,6 +1,6 @@
OData services treat collections of complex types differently than they treat collections of entity types.
This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
-The result of this difference is that it is almost always preferable to use entity types for collections rather than complex types; please see the exceptions [here](#exceptions).
+As a result, it is almost always preferable to use entity types for collections rather than complex types. See [exceptions](#exceptions) for acceptable usage of complex types in collections.
Let's use the following CSDL as an example:
```xml
From d321900f66e786ba6a937079d934e0c62898aa8c Mon Sep 17 00:00:00 2001
From: OlgaPodo <86168392+OlgaPodo@users.noreply.github.com>
Date: Fri, 1 Dec 2023 11:26:10 -0500
Subject: [PATCH 24/24] Update graph/collection-properties.md
Co-authored-by: Dan Kershaw [MSFT]
---
graph/collection-properties.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/graph/collection-properties.md b/graph/collection-properties.md
index 59f605a2..1add19fc 100644
--- a/graph/collection-properties.md
+++ b/graph/collection-properties.md
@@ -1,4 +1,4 @@
-OData services treat collections of complex types differently than they treat collections of entity types.
+Microsoft Graph treats collections of complex types differently than collections of entity types.
This is due to the nature of entity types being "individually addressable" (they have some key which uniquely identifies them within the collection) while complex types are not individually addressable.
As a result, it is almost always preferable to use entity types for collections rather than complex types. See [exceptions](#exceptions) for acceptable usage of complex types in collections.
Let's use the following CSDL as an example: