From 203f3768d32bf87bcefff374ccce57cdcbc6002b Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:20:20 -0700 Subject: [PATCH 1/6] Create draft-entity.md --- graph/patterns/draft-entity.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 graph/patterns/draft-entity.md diff --git a/graph/patterns/draft-entity.md b/graph/patterns/draft-entity.md new file mode 100644 index 00000000..c8137b15 --- /dev/null +++ b/graph/patterns/draft-entity.md @@ -0,0 +1,30 @@ +# "Draft" Entity + +Microsoft Graph API Design Pattern + +*A "draft" entity is one which can be used to temporarily store a subset of an entity that it is a draft of, avoiding validations that "real" instances of the entity would normally require.* + + +## 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 9e48600915ac805ad9ea06b52a59d53bf1a93335 Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:32:42 -0700 Subject: [PATCH 2/6] Update draft-entity.md --- graph/patterns/draft-entity.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/graph/patterns/draft-entity.md b/graph/patterns/draft-entity.md index c8137b15..9797742e 100644 --- a/graph/patterns/draft-entity.md +++ b/graph/patterns/draft-entity.md @@ -4,26 +4,29 @@ Microsoft Graph API Design Pattern *A "draft" entity is one which can be used to temporarily store a subset of an entity that it is a draft of, avoiding validations that "real" instances of the entity would normally require.* - ## Problem -*Describe the business context relevant for the pattern.* - -*Provide a short description of the problem.* +There are situations when a client only has a portion of the data required to create an entity at a given time. +In these situations, the client needs to store that partial data somewhere without requiring all of the data, and with allowing potentially invalid data to be present. ## Solution -*Describe how to implement the solution to solve the problem.* +The solution is to have a "draft" entity for the desired entity. +This "draft" can then be used to store the partial data until all of the data is available, at which time the "draft" can be used to create a "real" entity instance. +Doing this allows the storage of the partial data without compromising the integrity of the model for the "real" entity. + +```xml -*Describe related patterns.* +``` ## When to use this pattern -*Describe when and why the solution is applicable and when it might not be.* +The "draft" entity pattern will be useful for workloads that are backing a UI and expose entities which the UI creates through the use of a multi-page process. ## Issues and considerations -*Describe tradeoffs of the solution.* +This pattern should be avoided; instead, use some storage external to graph. +This pattern *may* be used as a stop-gap if a workload does not yet have the infrastructure for external storage; these entities should be deprecated immediately since they are only a stop-gap. ## Example From 697af4910829574e1c0c9c033908a5061eb1a5bc Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:44:46 -0700 Subject: [PATCH 3/6] Update draft-entity.md --- graph/patterns/draft-entity.md | 93 +++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/graph/patterns/draft-entity.md b/graph/patterns/draft-entity.md index 9797742e..632ace51 100644 --- a/graph/patterns/draft-entity.md +++ b/graph/patterns/draft-entity.md @@ -16,7 +16,29 @@ This "draft" can then be used to store the partial data until all of the data is Doing this allows the storage of the partial data without compromising the integrity of the model for the "real" entity. ```xml + + + + + + + + ... + + + + + + + + + ... + + + + + ``` ## When to use this pattern @@ -25,9 +47,76 @@ The "draft" entity pattern will be useful for workloads that are backing a UI an ## Issues and considerations -This pattern should be avoided; instead, use some storage external to graph. +This pattern should be avoided; instead, use some storage external to graph. TODO write down "why" This pattern *may* be used as a stop-gap if a workload does not yet have the infrastructure for external storage; these entities should be deprecated immediately since they are only a stop-gap. ## Example -*Provide a short example from real life.* +```HTTP +POST /someRealEntities +{ + "firstProp": "a value" +} + +400 Bad Request +{ + "error": { + "code": "badRequest", + "message": "The 'secondProp' property must not be null." + } +} +``` + +```HTTP +POST /someRealEntityDrafts +{ + "firstProp": "a value" +} + +201 Created +{ + "id": "{id}", + "firstProp": "a value", + "secondProp": null, + ... +} +``` + +```HTTP +POST /someRealEntityDrafts/{id}/realize + +400 Bad Request +{ + "error": { + "code": "badRequest", + "message": "The 'secondProp' property must not be null." + } +} +``` + +```HTTP +PATCH /someRealEntityDrafts/{id} +{ + "secondProp": 14 +} + +204 No Content +``` + +```HTTP +POST /someRealEntityDrafts/{id}/realize + +204 No Content +Location: /someRealEntities/{id2} +``` + +```HTTP +GET /someRealEntities/{id2} + +{ + "id": "{id2}", + "firstProp": "a value", + "secondProp": 14, + ... +} +``` From a99d22e2e6b81cccee6934a04fcab623912cd633 Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:47:40 -0700 Subject: [PATCH 4/6] Update draft-entity.md --- graph/patterns/draft-entity.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/graph/patterns/draft-entity.md b/graph/patterns/draft-entity.md index 632ace51..3a35c015 100644 --- a/graph/patterns/draft-entity.md +++ b/graph/patterns/draft-entity.md @@ -43,15 +43,17 @@ Doing this allows the storage of the partial data without compromising the integ ## When to use this pattern -The "draft" entity pattern will be useful for workloads that are backing a UI and expose entities which the UI creates through the use of a multi-page process. +The "draft" entity pattern will be useful for workloads that back a UI and expose entities which the UI creates through the use of a multi-page process. ## Issues and considerations This pattern should be avoided; instead, use some storage external to graph. TODO write down "why" -This pattern *may* be used as a stop-gap if a workload does not yet have the infrastructure for external storage; these entities should be deprecated immediately since they are only a stop-gap. +This pattern *may* be used as a stop-gap if a workload does not yet have the infrastructure for external storage; these entities must be deprecated immediately since they are only a stop-gap. ## Example +### {1} Create a "real" instance with only partial data, getting an error + ```HTTP POST /someRealEntities { @@ -67,6 +69,8 @@ POST /someRealEntities } ``` +### {2} Create a "draft" instance with only partial data + ```HTTP POST /someRealEntityDrafts { @@ -82,6 +86,8 @@ POST /someRealEntityDrafts } ``` +### {3} Try to realize the draft while it still only has partial data, getting an error + ```HTTP POST /someRealEntityDrafts/{id}/realize @@ -94,6 +100,8 @@ POST /someRealEntityDrafts/{id}/realize } ``` +### {4} Continue updating the draft with new data as the data becomes known + ```HTTP PATCH /someRealEntityDrafts/{id} { @@ -103,6 +111,8 @@ PATCH /someRealEntityDrafts/{id} 204 No Content ``` +### {5} Realize the draft once all data has been provided + ```HTTP POST /someRealEntityDrafts/{id}/realize @@ -110,6 +120,8 @@ POST /someRealEntityDrafts/{id}/realize Location: /someRealEntities/{id2} ``` +### {6} Retrieve the realized instance + ```HTTP GET /someRealEntities/{id2} From 5549c75771ab6f03b25d224ce2c42a0dfc39e50d Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:51:12 -0700 Subject: [PATCH 5/6] Update draft-entity.md --- graph/patterns/draft-entity.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/graph/patterns/draft-entity.md b/graph/patterns/draft-entity.md index 3a35c015..4bafbae7 100644 --- a/graph/patterns/draft-entity.md +++ b/graph/patterns/draft-entity.md @@ -47,7 +47,9 @@ The "draft" entity pattern will be useful for workloads that back a UI and expos ## Issues and considerations -This pattern should be avoided; instead, use some storage external to graph. TODO write down "why" +This pattern should be avoided; instead, use some storage external to graph. +Having entities that cannot be directly used by services because they are imcomplete and that have relaxed validation requirements effectively exposes an API that is equivalent to blob storage. + This pattern *may* be used as a stop-gap if a workload does not yet have the infrastructure for external storage; these entities must be deprecated immediately since they are only a stop-gap. ## Example From 25b24f61b448cebb231e8448876afdd963c8e77a Mon Sep 17 00:00:00 2001 From: Garrett DeBruin <16618938+corranrogue9@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:55:32 -0700 Subject: [PATCH 6/6] Update draft-entity.md --- graph/patterns/draft-entity.md | 1 + 1 file changed, 1 insertion(+) diff --git a/graph/patterns/draft-entity.md b/graph/patterns/draft-entity.md index 4bafbae7..5b7f368e 100644 --- a/graph/patterns/draft-entity.md +++ b/graph/patterns/draft-entity.md @@ -44,6 +44,7 @@ Doing this allows the storage of the partial data without compromising the integ ## When to use this pattern The "draft" entity pattern will be useful for workloads that back a UI and expose entities which the UI creates through the use of a multi-page process. +It is also useful for any circumstances where the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern) is effective, as this pattern is effectively a specialization of the builder pattern. ## Issues and considerations