From 95608ce4b8fe9242a484d7f66a14f63361b338fa Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Mon, 19 Jul 2021 12:38:19 -0700 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20AIP-121=20=E2=80=93=20Resource-orie?= =?UTF-8?q?nted=20Design?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aip/general/0121/aip.md | 78 +++++++++++++++++++++++++++++++++++++++ aip/general/0121/aip.yaml | 7 ++++ 2 files changed, 85 insertions(+) create mode 100644 aip/general/0121/aip.md create mode 100644 aip/general/0121/aip.yaml diff --git a/aip/general/0121/aip.md b/aip/general/0121/aip.md new file mode 100644 index 00000000..b4a5c03d --- /dev/null +++ b/aip/general/0121/aip.md @@ -0,0 +1,78 @@ +# Resource-oriented design + +Resource-oriented design is a pattern for specifying API services, based on +several high-level design principles (most of which are common to recent public +HTTP APIs): + +- The fundamental building blocks of an API are individually-named _resources_ + (nouns) and the relationships and hierarchy that exist between them. +- A small number of standard _operations_ (verbs) provide the semantics for + most common operations. However, custom operations are available in + situations where the standard operations do not fit. +- Stateless protocol: Each interaction between the client and the server is + independent, and both the client and server have clear roles. + +Readers might notice similarities between these principles and some principles +of [REST][]; resource-oriented design borrows many principles from REST, while +also defining its own patterns where appropriate. + +## Guidance + +When designing an API, consider the following (roughly in logical order): + +- The resources (nouns) the API will provide +- The relationships and hierarchies between those resources +- The schema of each resource +- The operations (verbs) each resource provides, relying as much as possible on + the standard operations. + +### Resources + +A resource-oriented API **should** generally be modeled as a resource +hierarchy, where each node is either a simple resource or a collection of +resources. + +A _collection_ contains resources of _the same type_. For example, a publisher +has the collection of books that it publishes. A resource usually has fields, +and resources may have any number of sub-resources (usually collections). + +**Note:** While there is some conceptual alignment between storage systems and +APIs, a service with a resource-oriented API is not necessarily a database, and +has enormous flexibility in how it interprets resources and operations. API +designers **should not** expect that their API will be reflective of their +database schema. In fact, having an API that is identical to the underlying +database schema is actually an anti-pattern, as it tightly couples the surface +to the underlying system. + +### Operations + +Resource-oriented APIs emphasize resources (data model) over the operations +performed on those resources (functionality). A typical resource-oriented API +exposes a large number of resources with a small number of operations on each +resource. The operations can be either the standard operations or custom +operations. + +**Note:** A custom operation in resource-oriented design does _not_ entail +defining a new or custom HTTP verb. Custom operations use traditional HTTP +verbs (usually `POST`) and define the custom verb in the URI. See AIP-136 for +more detail. + +Services **should** prefer standard operations over custom operations; the +purpose of custom operations is to define functionality that does not cleanly +map to any of the standard operations. Custom operations offer the same design +freedom as traditional [RPC][] APIs, which can be used to implement common +programming patterns, such as database transactions, import and export, or data +analysis. + +### Stateless protocol + +As with most public APIs available today, resource-oriented APIs **must** +operate over a stateless protocol: The fundamental behavior of any individual +request is independent of other requests made by the caller. + +In an API with a stateless protocol, the server has the responsibility for +persisting data, which may be shared between multiple clients, while clients +have sole responsibility and authority for maintaining the application state. + +[rest]: https://en.wikipedia.org/wiki/Representational_state_transfer +[rpc]: https://en.wikipedia.org/wiki/Remote_procedure_call diff --git a/aip/general/0121/aip.yaml b/aip/general/0121/aip.yaml new file mode 100644 index 00000000..0757c082 --- /dev/null +++ b/aip/general/0121/aip.yaml @@ -0,0 +1,7 @@ +--- +id: 121 +state: approved +created: 2019-01-26 +placement: + category: resource-design + order: 10 From 6046fa4027b49ca8a2d2b0afde952aec13cb97d8 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 31 Aug 2021 09:40:32 -0700 Subject: [PATCH 2/4] Incorporate @gibson042 feedback. Co-authored-by: Richard Gibson --- aip/general/0121/aip.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aip/general/0121/aip.md b/aip/general/0121/aip.md index b4a5c03d..7b08a163 100644 --- a/aip/general/0121/aip.md +++ b/aip/general/0121/aip.md @@ -29,7 +29,7 @@ When designing an API, consider the following (roughly in logical order): ### Resources A resource-oriented API **should** generally be modeled as a resource -hierarchy, where each node is either a simple resource or a collection of +hierarchy, where each node is either an individual resource or a collection of resources. A _collection_ contains resources of _the same type_. For example, a publisher @@ -53,8 +53,8 @@ resource. The operations can be either the standard operations or custom operations. **Note:** A custom operation in resource-oriented design does _not_ entail -defining a new or custom HTTP verb. Custom operations use traditional HTTP -verbs (usually `POST`) and define the custom verb in the URI. See AIP-136 for +defining a new or custom HTTP method. Custom operations use traditional HTTP +methods (usually `POST`) and define the custom verb in the URI. See AIP-136 for more detail. Services **should** prefer standard operations over custom operations; the From c5c326f4766f8c8ff9dd165de26fd0ca38f2079f Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 31 Aug 2021 09:48:09 -0700 Subject: [PATCH 3/4] Incorporate group feedback. --- aip/general/0121/aip.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/aip/general/0121/aip.md b/aip/general/0121/aip.md index 7b08a163..0ad57ec0 100644 --- a/aip/general/0121/aip.md +++ b/aip/general/0121/aip.md @@ -39,10 +39,8 @@ and resources may have any number of sub-resources (usually collections). **Note:** While there is some conceptual alignment between storage systems and APIs, a service with a resource-oriented API is not necessarily a database, and has enormous flexibility in how it interprets resources and operations. API -designers **should not** expect that their API will be reflective of their -database schema. In fact, having an API that is identical to the underlying -database schema is actually an anti-pattern, as it tightly couples the surface -to the underlying system. +designers **should not** tightly couple their API surface to their underlying +database system. ### Operations @@ -57,12 +55,16 @@ defining a new or custom HTTP method. Custom operations use traditional HTTP methods (usually `POST`) and define the custom verb in the URI. See AIP-136 for more detail. -Services **should** prefer standard operations over custom operations; the -purpose of custom operations is to define functionality that does not cleanly -map to any of the standard operations. Custom operations offer the same design -freedom as traditional [RPC][] APIs, which can be used to implement common -programming patterns, such as database transactions, import and export, or data -analysis. +Resources **should** include all of the standard operations; however, resources +**may** exclude some standard operations if there is a justification for doing +so (for example, a read-only resource would exclude all write operations). + +Similarly, services **should** prefer standard operations over custom +operations; the purpose of custom operations is to define functionality that +does not cleanly map to any of the standard operations. Custom operations offer +the same design freedom as traditional [RPC][] APIs, which can be used to +implement common programming patterns, such as database transactions, import +and export, or data analysis. ### Stateless protocol From e0bde6564899502d32a6fb44cb8e9a1f87726df8 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 31 Aug 2021 09:54:26 -0700 Subject: [PATCH 4/4] large -> arbitrary --- aip/general/0121/aip.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aip/general/0121/aip.md b/aip/general/0121/aip.md index 0ad57ec0..b41ac362 100644 --- a/aip/general/0121/aip.md +++ b/aip/general/0121/aip.md @@ -46,8 +46,8 @@ database system. Resource-oriented APIs emphasize resources (data model) over the operations performed on those resources (functionality). A typical resource-oriented API -exposes a large number of resources with a small number of operations on each -resource. The operations can be either the standard operations or custom +exposes a arbitrary number of resources with a small number of operations on +each resource. The operations can be either the standard operations or custom operations. **Note:** A custom operation in resource-oriented design does _not_ entail