Skip to content

Creation only defined via collections and POST in Hyper-Schema #581

Closed
@davidarnold

Description

@davidarnold

The current draft spec describes creation of new resources via submissionSchema on collection resources, noting that in HTTP this would correspond to POST. This is in line with the discussions that occurred in #47 and #48 as well as the precedent that AtomPub set.

However, REST is not CRUD and more specifically, the circa-2007 bijective mapping of C, R, U, D to POST, GET, PUT, and DELETE is flawed.

HTTP/1.1 does define a method with creation semantics and it is PUT. POST is defined as processing according to the resource's own semantics, with a nod to the very common practice of using it for adding or appending to a collection.

So, although it is well within the right of specs like AtomPub to define resource-specific POST creation semantics, it is not the canonical method in the HTTP uniform interface to create new resources.

Use cases

PUT creation of resources under a namespace

In my specific use case, we have several URI namespaces that permit creation of new resources. For example, creation of users is accomplished by performing a PUT of an appropriate JSON object to a URI template of /user/{user_id} where user_id is a client-generated UUID. I have been struggling to find a standard which would communicate to API clients that this operation is permissible.

Under the current Hyper-Schema draft, it seems I would have to convert /user from a hierarchical URI namespace into a first-class collection resource and change the interaction pattern to be a POST to that new resource instead of a direct PUT to the final URI of the user.

Given that /user is currently not a valid resource in our hierarchy, and for security reasons cannot list all users, it seems odd that I would have to create a permanently empty resource just to house a shell collection that can anchor the creation semantics. Also, switching to POST would destroy the ability of clients to use PUT as a hassle-free "upsert" mechanism, instead having to decide or remember whether they have already created the user and change their approach if so.

PUT creation of non-collection sub-resources

In a more hypothetical example (since the last one could trigger debate over the collection model), you can foresee examples where a resource may permit creation of a sub-resource that is not a collection at all. In other words, the sub-resource has 0..1 cardinality instead of 0..*

Suppose there is an API providing access to scholarly articles. Each article is available under /article/{article_id} and may contain an optional sub-resource for its bibliography under /article/{article_id}/bibliography. Also, it may provide free access to a curated summary under /article/{article_id}/summary.

It makes sense that a new bibliography or summary could be created on the site via direct PUT to the appropriate URI. It is also entirely unclear how this situation could be contorted to use collection patterns to achieve the goal.

Proposed solution

I found the use of targetSchema in the draft spec odd, considering that it is earmarked specifically for use in retrieval, replacement, and patching, all of which are more authoritatively described by the resource itself. In fact, the document admits that the targetSchema is advisory in nature and that client applications are free to completely ignore it.

However, targetSchema makes perfect sense to me if its presence is intended to indicate that the link, regardless of its rel type, admits creation using the designated schema object. Since the resource on the other end of the link may not exist yet, it cannot link to a schema document that describes how to create it. The burden has to be on the referring resource to describe how to create its related resources.

Another benefit is that this creation schema is free to diverge slightly from the resource's primary schema to serve the common scenario of creation data excluding certain properties (e.g. system timestamps).

Since I am ignorant to the context on why a duplicative and non-authoritative property would exist outside of creation, I would tentatively propose that the existence of targetSchema should convey an explicit creation semantic, and be discouraged for use in other scenarios.

Retrieval and replacement are better served by the authoritative schema linked by the live representation of the current state of the resource, patching would require its own schema (and possibly its own media type), and as the draft states, targetSchema is nonsensical with regard to deletion.

In conclusion, targetSchema as an enabler of arbitrary resource creation would allow Hyper-Schema to produce level 3 RMM REST applications in a non-intrusive and discoverable way, without relying on industry conventions or aging design patterns.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions