From 14c01c00e8fe61f25f236135065f47121523c39e Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Mon, 31 Jul 2023 07:16:01 -0700
Subject: [PATCH 1/5] Create snapshots.md
---
graph/patterns/snapshots.md | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 graph/patterns/snapshots.md
diff --git a/graph/patterns/snapshots.md b/graph/patterns/snapshots.md
new file mode 100644
index 00000000..26336e73
--- /dev/null
+++ b/graph/patterns/snapshots.md
@@ -0,0 +1,30 @@
+# Pattern name
+
+Microsoft Graph API Design Pattern
+
+*Provide a short description of the pattern.*
+
+
+## Problem
+
+*Describe the business context relevant for the pattern.*
+
+*Provide a short description of the problem.*
+
+## Solution
+
+*Describe how to implement the solution to solve the problem.*
+
+*Describe related patterns.*
+
+## When to use this pattern
+
+*Describe when and why the solution is applicable and when it might not be.*
+
+## Issues and considerations
+
+*Describe tradeoffs of the solution.*
+
+## Example
+
+*Provide a short example from real life.*
From 90720d08e359a086bf2181f9ab0aa679b9e15573 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Mon, 31 Jul 2023 07:40:01 -0700
Subject: [PATCH 2/5] Update snapshots.md
---
graph/patterns/snapshots.md | 51 ++++++++++++++++++++++++++++++++-----
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/graph/patterns/snapshots.md b/graph/patterns/snapshots.md
index 26336e73..c9acbd4a 100644
--- a/graph/patterns/snapshots.md
+++ b/graph/patterns/snapshots.md
@@ -1,24 +1,61 @@
-# Pattern name
+# Snapshots
Microsoft Graph API Design Pattern
-*Provide a short description of the pattern.*
-
+*The snapshots pattern allows access to data for an individual resource even when that resource no longer exists, while still allowing to easily correlate references to that resource.*
## Problem
-*Describe the business context relevant for the pattern.*
+There are often times when data on an entity (usually a subset) needs to be exposed even after the entity has been removed or updated.
+This data is representating that entity during a snapshot in time.
+However, simply duplicating the data prevents correlating that snapshot data with the entity itself or with other data that are also snapshots in time.
-*Provide a short description of the problem.*
+An example would be a log of `user`s who have signed in.
+The log could have an entry for when the `user` signed in, as well as details about the user.
+But without a way to correlate this sign in data to the `user` itself, further investigations becomes difficult.
## Solution
-*Describe how to implement the solution to solve the problem.*
+The solution is to have a complex type which represents the resource as a snapshot in time, while also providing a navigation property to the resource itself.
+The following CSDL demonstrates this with the `user` sign in example:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-*Describe related patterns.*
+
+
+
+
+
+
+
+```
## When to use this pattern
+//// TODO give alternative, anti-pattern approaches
*Describe when and why the solution is applicable and when it might not be.*
## Issues and considerations
From 158b797146d286b9e2b257a78297ac49fb5ffe2d Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Mon, 31 Jul 2023 07:52:50 -0700
Subject: [PATCH 3/5] Update snapshots.md
---
graph/patterns/snapshots.md | 72 +++++++++++++++++++++++++++++++++----
1 file changed, 66 insertions(+), 6 deletions(-)
diff --git a/graph/patterns/snapshots.md b/graph/patterns/snapshots.md
index c9acbd4a..c19c56ef 100644
--- a/graph/patterns/snapshots.md
+++ b/graph/patterns/snapshots.md
@@ -12,12 +12,12 @@ However, simply duplicating the data prevents correlating that snapshot data wit
An example would be a log of `user`s who have signed in.
The log could have an entry for when the `user` signed in, as well as details about the user.
-But without a way to correlate this sign in data to the `user` itself, further investigations becomes difficult.
+But without a way to correlate this signin data to the `user` itself, further investigations becomes difficult.
## Solution
The solution is to have a complex type which represents the resource as a snapshot in time, while also providing a navigation property to the resource itself.
-The following CSDL demonstrates this with the `user` sign in example:
+The following CSDL demonstrates this with the `user` signin example:
```xml
@@ -47,20 +47,80 @@ The following CSDL demonstrates this with the `user` sign in example:
```
+TODO example with nested snapshots?
+
## When to use this pattern
-//// TODO give alternative, anti-pattern approaches
-*Describe when and why the solution is applicable and when it might not be.*
+This pattern should be used whenever one resource is referring to another resource, but the data available for the second resource is specific to a point in time that the first resource is referring to.
+Logs, reports, and events are the most common examples of this.
## Issues and considerations
-*Describe tradeoffs of the solution.*
+When these snapshot situations arise, it is common to attempt putting the `user` data on the `userSignIn` directly.
+This should be avoided because it gives the impression that the data belongs to the signin event.
+It also can cause naming conflicts.
+Using our above `user` example, let's say that the `userSignIn` wants to include the `displayName` of the `user`:
+
+```xml
+
+
+
+
+
+
+
+ ...
+
+
+
+
+
+
+
+
+
+
+
+```
+
+This CSDL ships to customers who begin using it.
+They relate back to the workload that they would find it very useful to have the time the `user` was created in the signin logs so that they can do certain kinds of investigations.
+Following the same pattern, we sould update the CSDL:
+
+```xml
+
+
+
+
+
+
+
+ ...
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Except now, the `createdDateTime` property *appears* to be indicating when the `userSignIn` was created.
+This could have been mitigated if the original CSDL had named the property `userDisplayName`, so the new property would be `userCreatedDateTime`.
+However, doing this indicates a clear structuring of the data, which is already known to be the case because the `user` entity exists in the first place.
+The guidance would generally be to have a navigation property to the entity referred to in such cases, but more generally the guidance is to factor these properties into their own type.
+In the snapshot case, we want to do both: we factor the properties in a "snapshot" complex type, *and* that complex type has a navigation property to the entity being referred to.
## Example
From 5af045380d1575c80d54b2b93e75ed21874f9d8b Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Mon, 31 Jul 2023 07:58:33 -0700
Subject: [PATCH 4/5] Update snapshots.md
---
graph/patterns/snapshots.md | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/graph/patterns/snapshots.md b/graph/patterns/snapshots.md
index c19c56ef..109644a0 100644
--- a/graph/patterns/snapshots.md
+++ b/graph/patterns/snapshots.md
@@ -124,4 +124,26 @@ In the snapshot case, we want to do both: we factor the properties in a "snapsho
## Example
-*Provide a short example from real life.*
+### {1} Retrieve signin events that contain user data
+
+```HTTP
+GET /userSignIns
+
+200 OK
+{
+ "value": [
+ {
+ "id": "{signinid}",
+ "attemptDateTime": "2023-07-31 7:56:00 AM",
+ "requestedPermissions": [
+ "User.Read"
+ ],
+ "user": {
+ "id": "00000000-0000-0000-0000-000000000001",
+ "displayName": "some display name",
+ "userPrincipalName": "user@domain.com"
+ }
+ }
+ ]
+}
+```
From ae90ac48f026ce78c604087bf4a8765aa3c71ac3 Mon Sep 17 00:00:00 2001
From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com>
Date: Mon, 31 Jul 2023 08:00:18 -0700
Subject: [PATCH 5/5] Update snapshots.md
---
graph/patterns/snapshots.md | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/graph/patterns/snapshots.md b/graph/patterns/snapshots.md
index 109644a0..f409448d 100644
--- a/graph/patterns/snapshots.md
+++ b/graph/patterns/snapshots.md
@@ -39,7 +39,7 @@ The following CSDL demonstrates this with the `user` signin example:
-
+
@@ -138,12 +138,27 @@ GET /userSignIns
"requestedPermissions": [
"User.Read"
],
- "user": {
+ "userSnapshot": {
"id": "00000000-0000-0000-0000-000000000001",
"displayName": "some display name",
"userPrincipalName": "user@domain.com"
}
- }
+ },
+ ...
]
}
```
+
+### {2} Retrieve the user associated with a signin event
+
+```HTTP
+GET /userSignIns/{signinid}/userSnapshot/user
+
+200 OK
+{
+ "id": "00000000-0000-0000-0000-000000000001",
+ "displayName": "some display name",
+ "userPrincipalName": "user@domain.com",
+ ...
+}
+```