[Specifications] Using collection to create resources vs adding members (#237)

tpluscode has just created a new issue for https://github.com/HydraCG/Specifications:

== Using collection to create resources vs adding members ==
## Describe your API requirement

This a question not specifically related to Hydra as I have seen similar discussion for other systems too. 

A typical scenario for using a collection resource, in our case an instance of `hydra:Collection`, is to do a `POST` request with the intended member representation

```http
POST /users
Content-Type: text/turtle

prefix schema: <http://schema.org/>
<> a schema:Person ; schema:name "John Doe"
```

For the above request, the server could create a new identifier, for example by slugifying the name to produce a URL `/user/john-doe`.

The question is, how an API would expose the functionality of adding **existing resources** for the client to understand.

## Solution(s)

I consider implementing a generic supported operation handler, which would work slightly differently depending on the operation's definition.

### Base operation

The core would be just a POST, expecting `api:User` as payload

```turtle
api:UserCollection
  hydra:supportedOperation [
    hydra:method "POST" ;
    hydra:expects api:User ;
  ] ;
.
```

### Operation to create users

```diff
api:UserCollection
  hydra:supportedOperation [
+   rdf:type schema:CreateAction ;
    hydra:method "POST" ;
    hydra:expects api:User ;
  ] ;
.
```

By adding the `schema:CreateAction` type, the client would be informed that the operation creates new users. A request containing `<> a api:User` or `[] a api:User` would have these resources created with a server-defined URI as mentioned above

### Operation to add resources to collection

Now the fun part: How to change an operation so that the client and the server know that they should send existing resources. And what would the request look like?

```diff
api:UserCollection
  hydra:supportedOperation [
+   rdf:type schema:UpdateAction ;
    hydra:method "POST" ;
-   hydra:expects api:User ;
+   hydra:expects ?? ;
  ] ;
.
```

By typing the operation as `schema:UpdateAction` but not the other, the server would only allow payloads with existing user representations. It should be enough to send just the identifiers, right? To add two members to collection, could that be either

```turtle
<user/John> a api:User .
<user/Jane> a api:User .
```

or, using a different `expects`:

```turtle
POST <users>

<users> hydra:member <user/John> ; <user/Jane> .
```

### Having it both ways?

Given what I've just realised when writing the previous section, two alternative operations could be necessary to have a single collection resource allow both kinds of requests. Combined:

```diff
api:UserCollection
  hydra:supportedOperation [
    rdf:type schema:CreateAction ;
    hydra:method "POST" ;
    hydra:expects api:User ;
  ] , [
    rdf:type schema:UpdateAction ;
    hydra:method "POST" ;
    hydra:expects ?? ;
  ] ;
.
```

Please view or discuss this issue at https://github.com/HydraCG/Specifications/issues/237 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 27 April 2021 19:39:47 UTC