Closed elf-pavlik closed 6 years ago
I've spent some time thinking about it. I've ended up with a conclusion that creating a resource is one thing, linking it with another resource (i.e. collection to be specific) is another matter.
Regardless the approach (rich command/action vocabulary or rich relations vocabulary), creating a resource may with POST, but may not end up with adding newly created resource to the collection. This is how POST works - we send a resource for processing, but we don't really know on what will happen. Situation with PUT is a bit better - hierarchy of resources expressed with segments in the resource's URL may imply that the putted resource will be added to the collection - stil it's not a mandatory behavior. Anyway, what if we want to add to the collection a resource of which URL is not related to the target collection in any way (i.e. URL of a person we want to add as a friend)?
Finally, I've ended up with something like this:
0. Begin
1. Do I know the IRI of the resource I create?
If yes, go to 4, otherwise go to 2.
2. Is there a POST operation available?
If yes, go to 3, otherwise go to 7.
3. POST new resource to the operation pointed URL.
Obtain a Location header and assigned it to the resource's IRI.
Go to 6.
---
4. Is there a PUT operation available?
If yes, go to 5, otherwise go to 7.
5. Assign the URL I create to the resource's IRI and PUT the resource to that URL.
---
6. LINK the resource to the designated target resource (i.e. a collection)
using a desired relation.
Type of the relation "describing" semantically as a collection concluding
is a subject for discussion.
7. Abort, unable to perform action.
8. End
Steps 1-3 are related to creating a resource if we don't know on how to create IRI of the resource being created. Steps 4-5 are related to creating a resource assuming we know on how to created the IRI mentioned. Step 6 is actually an operation that "adds" newly created resource to the collection - this is the only operation that should make the client sure of what will happen. Please not that only step 2 (which may be treated as a fallback for dumb clients) is not idempotent. What do you think about that?
Please keep in mind that POST != create. From the spec
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.
If your snippet above describes a specific API, that's fine. If it describes the client's behavior, it is not as it simply can't infer the server's behavior (semantics) by just looking at the HTTP methods.
I think CreateAction with HTTP PUT makes an interesting example of operation which requires IRI other than the resource which advertises it. It seems in some ways similar to hydra:search
which range includes hydra:IriTemplate
.
@lanthaler since hydra:Operation
doesn't provide a way to specify hydra:IriTemplate
it seems that we may not use schema:CreateAction
with both HTTP POST and HTTP PUT. BTW since we consider recommending http://schema.org/docs/actions.html we may also want to have some explanation about http://schema.org/target
Also hydra:search
doesn't work as an operation so one shouldn't look for schema:SearchAction
. Having something like schema:target
which range includes IRI and hydra:IriTemplate
(and defaults to IRI of the resource advertising the action) we could use schema:CreateAction
with either POST or PUT and also treat a search as schema:SearchAction
hierarchy of resources expressed with segments in the resource's URL may imply that the putted resource will be added to the collection
Sorry to say, that is completely out of place. URL structures should imply nothing. It's just an identifier.
hydra:Operation
doesn't provide a way to specifyhydra:IriTemplate
So maybe let's work on that. Is there a reason why it shouldn't?
A bit on the side, I remember thinking about minting URIs for operations (mostly PUT
which is discussed here). My idea was to simply combine the parameters of a hypothetical URI Template and the one of the operation.
For example, if the client was to PUT /article/{title}
that title
variable could also be part of the operation's parameters. That way we have a uniform way to handle user input (think generating a <form>
). The title
property is just another field along with other stuff that go in the request body such as publishDate
, abstract
, author
, etc.
For use cases I would like to use it for, I only need a way to specify that variable in a template comes as unique identifier UUID, CUID, GUID
For example, if the client was to
PUT /article/{title}
that title variable could also be part of the operation's parameters
I worry that in use case you mention, when later updating a title one might also expect IRI to change as well.
I worry that in use case you mention, when later updating a title one might also expect IRI to change as well.
No because the operation on an existing resource will be different. You would be operating on a concrete URI.
But that's not the essence of what I meant. The logic is that the template's variables would be treated just as any other operation parameter. Whether that same variable exists in the operation or not. If #118 was agreed upon that could become something to work on in Heracles.
I think hydra:IriTemplateMapping
(example 15) and hydra:SupportedProperty
(example 8) already work in quite similar similar way. At the same time I think we need to have them distinct, for example I would have hydra:IriTemplateMapping
for UUID but I wouldn NOT want to include that UUID as hydra:SupportedProperty
.
At the same time we may want to have a way that if resource has both hydra:IriTemplateMapping
and hydra:SupportedProperty
for dc:title
, both expect a value from 'expected' resource.
I don't think I understood your comment ;)
The logic is that the template's variables would be treated just as any other operation parameter.
In your example of dc:title
, it would appear in both hydra:IriTemplateMapping
and hydra:SupportedProperty
in some kind of foo:Article a hydra:Class
. And the operation would have [] hydra:expects foo:Article
. The operation itself would not directly have any 'parameter' in some way related to dc:title
. Let's maybe all try to put more JSON-LD snippets in our comments to show more clearly what we have in mind?
I think you got it just the way I had in mind
Please keep in mind that POST != create. From the spec
I know. The closest is PUT, but it requires quite a knowledge from the client (URL).
hierarchy of resources expressed with segments in the resource's URL may imply that the putted >>resource will be added to the collection
Sorry to say, that is completely out of place. URL structures should imply nothing. It's just an identifier.
In our cases - that's true. There are specs that indeed a URL hierarchy actually matters.
hydra:Operation doesn't provide a way to specify hydra:IriTemplate
So maybe let's work on that. Is there a reason why it shouldn't?
Agreed - I strongly support templated operations. I tried to use what's available in the spec in my URSA server/client solution, but the outcome is not very "healthy".
For example, if the client was to PUT /article/{title} that title variable could also be part of the >operation's parameters.
Not a very good example, as indeed title could vary in time causing the URL to change, but with a property mapped as unique identifier, client could take an advantage of the templated operations. This should be an extension to the core Hydra anyway - I don't see Hydra defining what a unique identifier is. Implementations can rely on owl:inverseFunctionalProperty, but from the template point of view it should be just another parameter. Only difficulty I see is that currently the spec says the the Iri template parameter is of a given property from the server point of view (i.e. server maps this parameter to that property) - it doesn't imply that client should use value of that very property when creating Iris.
Please fix the formatting in your last post @alien-mcl
If more of us could be made owners or administrators of this repository, we could help each other edit comments to improve formatting and such. I have itching fingers for things like these and would love to help if I had access to. ;-)
I'm trying to implement that case and I experience serious issues related on how to do this.
I was thinking about a situation where I have two collections of events of type schema:Event
and people of type schema:Person
. Every single schema:Person
can have a schema:perfomerIn
relation with an event,
I see no real possibility of implementing a situation when a client wants to PUT a schema:Event
to /api/people/1/perfomerIn
without instructing it on how to create a proper URL, which would be in this case /api/people/1/perfomerIn/2
(I wanted to PUT
/api/events/2
to create a
</api/people/1> schema:perfomerIn </api/events/1>
).
Indeed server could provide all possible PUT
URLs of events, but this is not a good approach. It's fine with closed set of values, but open sets are no good in that situation.
Any ideas?
@alien-mcl: Why do you need to use PUT
? Isn't this discussion only about being able to use PUT
in addition to POST
, not requiring PUT
? If POST
works better for your scenario (which it sounds like it does), then why not use POST
?
I think we should go with one step at a time, while we have dedicated issue for #134 here we can start with a UC#5 Creating a new event and just use PUT instead of POST. Looking at UC#1 Entry point, as I suggested in https://github.com/HydraCG/Specifications/issues/3#issuecomment-336635276 the definition of action should stay almost the same. Currently we have
{
"@context": "/api/context.jsonld",
"@id": "/api",
"@type": "hydra:EntryPoint",
"collection": [
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
"manages": {
"property": "rdf:type",
"object": "schema:Event"
},
"operation": {
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "POST",
"expects": "schema:Event"
}
}
]
}
If service chooses to use PUT not POST to create, it would have something like
{
"@context": "/api/context.jsonld",
"@id": "/api",
"@type": "hydra:EntryPoint",
"collection": [
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
"manages": {
"property": "rdf:type",
"object": "schema:Event"
},
"action": {
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "PUT",
"expects": "schema:Event",
"targetTemplate": {
"@type": "hydra:IriTemplate",
"hydra:template": "/api/events/{?uuid}",
"hydra:mapping": {
"hydra:variable": "uuid",
"hydra:property": "id:uuid",
"hydra:required": true
}
}
}
}
]
}
Once we have at least one possible solution for simple case like this, we can see if it still works with more complex case (like relating existing resources), but I see benefits with starting from simple case.
@lanthaler since
hydra:Operation
doesn't provide a way to specifyhydra:IriTemplate
it seems that we may not useschema:CreateAction
with both HTTP POST and HTTP PUT
I realize it is not properly documented but the intention was always that operations would work on IriTemplates just as they work on resources... otherwise things like hydra:search
wouldn't work.
Isn't hydra:search
a link?
Regardless, it's not clear indeed. I think the use of templates with operations has come up a few times and I never realised what you just wrote :)
As a followup to the comment above, here are Pavlik's snippets rewritten by attaching the operation to IRI template.
Nothing changes if the operation is POST
on the collection itself:
{
"@context": "/api/context.jsonld",
"@id": "/api",
"@type": "hydra:EntryPoint",
"collection": [
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
"manages": {
"property": "rdf:type",
"object": "schema:Event"
},
"operation": {
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "POST",
"expects": "schema:Event"
}
}
]
}
If service chooses to use PUT not POST to create, it would link to the resource to PUT to and have the operation on that
{
"@context": "/api/context.jsonld",
"@id": "/api",
"@type": "hydra:EntryPoint",
"collection": [
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
"manages": {
"property": "rdf:type",
"object": "schema:Event"
},
"hydra:addMember": {
"@id": "/api/events/new",
"operation": {
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "PUT",
"expects": "schema:Event"
}
}
}
]
}
If the IRI of the resource used to create isn't known an IRITemplate can be used without changing the above much:
{
"@context": "/api/context.jsonld",
"@id": "/api",
"@type": "hydra:EntryPoint",
"collection": [
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
"manages": {
"property": "rdf:type",
"object": "schema:Event"
},
"hydra:addMember": {
"@type": "IriTemplate",
"template": "/api/events/{slug}",
"mappings": [{
"variable": "slug"
}],
"operation": {
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "PUT",
"expects": "schema:Event"
}
}
}
]
}
The only difference is that instead of a concrete "@id"
, the target is an hydra:IrITemplate
. To perform the request first the template needs to be resolved.
To address the issue of how the client "knows" that the said PUT
operation actually adds members to the parent collection, there are two hints: "schema:CreateAction"
and the hypothetical link relation hydra:addMember
.
In addition, as I mentioned in the call, we could have extra metadata on the operation itself. Something like:
{
"@type": ["hydra:Operation", "schema:CreateAction"],
"hydra:sideEffects": [{
"@type": "hydra:AddLinkEffect",
"property": "hydra:member",
"subject": "/api/events"
}]
}
Something like that? A side-effects
block which can be used as an extension point for goal-oriented clients to describe how any operation affects other resources. In this example the AddLinkEffect
(excuse poor naming) could describe the a /api/events hydra:member _:new_member
triple will be created.
Similarly it could describe that a DELETE
operation on resource will remove it from other collections. Going back to the Vimeo example we could have
{
"@id": "/users/elfpavlik/likes/144522067",
"operation": {
"@type": ["hydra:Operation", "schema:DeleteAction"],
"hydra:sideEffects": [{
"@type": "hydra:BreakLinkEffect",
"property": "hydra:member",
"subject": "/users/elfpavlik/likes"
}, {
"@type": "hydra: BreakLinkEffect",
"property": "hydra:member",
"subject": "/videos/144522067"
}]
}
}
Such extension point would allow various built-in and API-specific ways to describe what the operation does.
@tpluscode: Thanks for the elaborate examples, they help (at least me) when discussing this. Is there any particular reason why "hydra:addMember"
has an @id
, but none of the other operations in your examples?
Also, why are there seemingly so many different ways to embed operations? Shouldn't they all go into an operation
array?
In relation to the client understanding what an operation does, I was under the impression that @type
in combination with expects
was all that's needed to decipher the operation semantics? If @type
states schema:CreateAction
and expects
is set to schema:Event
, isn't it obvious that the operation creates events (within the current scope, being the hydra:Collection
)? Do we need to complicate this further?
Sorry, but I don't fancy the hydra:BreakLinkEffect
proposal, as it sounds way too finegrained to belong in the core vocabulary. Are side effects something we need to tackle in version 1.0 of Hydra? Isn't that something we can figure out whether is required and add on along with a plethora of other things we're guaranteed to not cover in 1.0?
Lastly, what's the difference between the properties prefixed with hydra:
(such as hydra:addMember
) and those who doesn't (such as expects
)? I assumed both of these fell under the Hydra namespace and thus should preferably be the default (removing the need for the hydra:
prefix)?
To unify the different examples given above, this is how I would want to express the three different create operations:
{
"@context": "/api/context.jsonld",
"@id": "/api",
"@type": "hydra:EntryPoint",
"collection": [
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
// Renamed "manages" to "contains" and made it a string instead of object, for simplicity.
"contains": "schema:Event",
// Single "operation" array to contain all operations regardless of their semantics.
"operation": [
{
// All operations can be uniformly identified by their @id.
"@id": "/api/events/new",
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "POST",
"expects": "schema:Event"
}, {
"@id": "/api/events/new",
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "PUT",
"expects": "schema:Event",
// If the target is a string, it's implicitly of @type: '@id'. I have no idea if this is possible with JSON-LD, but this flexibility would be neat and make the format simpler.
"target": "/api/events/06c31878411c45ffa0996c45a3a58eb1",
}, {
"@id": "/api/events/new",
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "PUT",
"expects": "schema:Event",
// If the target is an object, it will most likely always be a 'hydra:IriTemplate', possibly making the @type property automatically inferred and obsolete (I hope)?
"target": {
"@type": "hydra:IriTemplate",
"template": "/api/events/{?uuid}",
// No 'hydra:' prefix if possible.
"mapping": {
"variable": "uuid",
"property": "id:uuid",
"required": true
}
},
}
]
}
]
}
With this uniformity, it's pretty easy to write a client, since all operations can be handled the same way. You just need to see if there's a target
property, and if it is, use it as the URI (or as a template to build the URI) to perform the operation against.
Please don't hesitate to out all the errors I've made above. 😃
NOTE: I'm not saying a collection will actually have three different ways to create members, I'm just including all variants so they can be compared in close proximity.
To address the issue of how the client "knows" that the said PUT operation actually adds members to the parent collection, there are two hints: "schema:CreateAction" and the hypothetical link relation hydra:addMember.
I would really like to find a way that client will discover specific action in the same way, and description of the action will instruct it what operation (and on which resource) it has to perform to accomplish given action. IMO client shouldn't have to understand anything like hydra:addMember
in addition to schema:CreateAction
just because PUT on another resource handles this action instead of POST on the same resource (the collection).
In approach where I suggested, we could define
hydra:operation rdfs:subPropertyOf hydra:action
Which makes hydra:operation
a more specific action, where the subject in the statement using it acts also as a target
of that operation.
In JSON-LD the @context
could in addition include alias
"target": { "@reverse": "hydra:operation" }
We could also consider optional
This way, client will just need to:
hydra:Operation
which resource references via hydra:action
(which automatically includes all the resources referenced by more specific hydra:operation
).@type
, hydra:expects
and other possible criteriahydra:method
and target
identified by:
hydra:operation
if resource used more specific hydra:operation
target
(reverse use of hydra:resource
) providing IRI for operation if resource used broader hydra:action
hydra-pr:targetTemplate
providing hydra:IriTemplate
based on which client can construct IRI which will serve as target
of the operation.@asbjornu:
Is there any particular reason why
"hydra:addMember"
has an@id
Indeed there is. This is not an operation. It's a link. In triples it would be represented as </api/events> hydra:addMember </api/events/new>
. I realise that the I chose the predicate poorly. The intention was for a link between the collection and the resource used to created new members. The target
in the terminology you use.
So again, the target of the operation is always the parent in JSON-LD. The subject in the ?subject hydra:operation ?operation
triple. Hence, no need for an explicit target
property.
If
@type
statesschema:CreateAction
and expects is set toschema:Event
, isn't it obvious that the operation creates events (within the current scope, being thehydra:Collection
)? Do we need to complicate this further?
Maybe we don't but I do see the value in letting the client know that the created event will become a member of a given collection. This way you can, optionally, describe side effects on other resources shall you need to.
Sorry, but I don't fancy the hydra:BreakLinkEffect proposal, as it sounds way too finegrained to belong in the core vocabulary
I agree. You're right that the core should only include an abstract term. An extension point for implementation by specialised vocabularies. I just wanted this as an illustration of how the idea can be executed.
This is also something not crucial for a generic client. It could safely ignore this description and still be able to successfully perform the operation.
So maybe this should probably be the deciding factor in any argument whether something belongs to the core vocabulary - is it necessary for a generic client. Anything else should be an extension.
Lastly, what's the difference between the properties prefixed with
hydra:
and those who doesn't?
No difference I think. However we're accustomed that we don't prefix the common terms. I prefer to add prefix to something that isn't officially in the vocabulary.
With this uniformity, it's pretty easy to write a client
We already have this uniformity. The target is always the parent. @id
or hydra:templated
to be filled in.
@elf-pavlik are you sure that your proposal is simple?
I still don't understand the distinction between operation
and action
. This is pure confusion.
Also, the steps are more elaborate than I think you let us believe ;). Some observations to consider:
instances of
hydra:Operation
which resource references viahydra:action
no idea what that means
perform operation (handle action)
do you see how these overlapping terms are just a distraction?
reverse direction of
hydra:operation
if resource used more specifichydra:operation
again, more complicated than "the target is the parent. period"
hydra-pr:targetTemplate
providinghydra:IriTemplate
ditto, if the parent is a template use that. and no need for additional core term
again, more complicated than "the target is the parent. period" [...] ditto, if the parent is a template use that. and no need for additional core term
I would prefer that we don't discuss it in terms of some specific framing of JSON-LD and keep in mind that people may prefer to use Turtle or any other serialization. I'll try to stick to Statement (Triple or Quad) and s, p, o
in all further comments!
instances of hydra:Operation which resource references via hydra:action
no idea what that means
all the operations matching
</some-resource> hydra:action ?operation
I still don't understand the distinction between
operation
andaction
. This is pure confusion.
As discussed in #3 currently hydra:operation
implies that target
of an Operation
("target"" { "@reverse": "operation" }
) while schema:potentialAction
does not act as reverse of `schema:target. This allows resources in schema.org to reference instances of schema:Action
which have schema:target
other than the resource itself. I would like us to consider also providing such option in Hydra.
Is there any particular reason why
"hydra:addMember"
has an@id
Indeed there is. This is not an operation. It's a link. In triples it would be represented as
</api/events> hydra:addMember </api/events/new>. I realise that the I chose the predicate poorly. The intention was for a link between the collection and the resource used to created new members. The
target` in the terminology you use.
Does it mean that in UC#1 Entry point we would have to add statement </api/events> hydra:addMember </api/events>
?
{
"@id": "/api/events",
"title": "List of events",
"@type": "hydra:Collection",
"manages": {
"property": "rdf:type",
"object": "schema:Event"
},
+ "hydra:addMember": "/api/events",
"operation": {
"@type": ["hydra:Operation", "schema:CreateAction"],
"title": "Create new event",
"method": "POST",
"expects": "schema:Event"
}
}
In approach I propose we could simply reuse schema:AddAction
instead having to define hydra:addMember
. But now I notice that if we would have
</api/events> schema:potentialAction [
a hydra:Operation, schema:AddAction, schema:CreateAction ;
schema:target </api/events/new>
] .
schema:AddAction
should apply to </api/events> but schema:CreateAction should apply to </api/events/new>
so we get ugly ambiguity here. We could still have
</api/events> schema:potentialAction [
a hydra:Operation, schema:AddAction ;
schema:target </api/events/new>
] .
</api/events/new> hydra:operation [
a hydra:Operation, schema:CreateAction
] .
@tpluscode in your snippets the instance of hydra:Resource
or hydra:IriTemplate
on object
position in a statement with hydra:addMember
, advertised only single operation. In case when that resource or template advertises (references via hydra:operation
) more than one instances of hydra:Operation
, how the client knows which of those operations to choose?
It seems like clients needs to follow those two steps
1) starting from a collection follow hydra:addMember
to discover a resource or template handling adding members to that collection
2) on that discovered resource or template follow all the hydra:operation
and select the one with with [] rdf:type hydra:Operation, schema:CreateAction .
This seems pretty similar to what I have in mind
1) starting from a collection follow schema:potentialAction
and select the one with [] rdf:type schema:AddAction .
2) from selected operation follow schema:target
(or hydra:operation
but in reverse direction) to discover resource or template handling that action
3) on that discovered resource or template follow all the hydra:operation
and select the one with with [] rdf:type hydra:Operation, schema:CreateAction .
so the last steps look exactly the same, it only differs on how client discovers the resource or template which handles intended action, and if we specify intended action using schema:Action
(rdfs:Class
) or hydra:Link
(rdf:Property
). I think we could try to see how those two approaches would work with #134
What I like about those both approaches, they don't rely on particular choice of HTTP method in the operation, which I understood @alien-mcl explores in https://github.com/HydraCG/Heracles.ts/pull/18 IMO we should only rely statements using terms from Hydra vocab and something like schema.org actions and don't try to infer things from some particular choice of HTTP methods.
I'll try to stick to Statement (Triple or Quad) and s, p, o in all further comments!
Sort of agree because remember, not all readers here will be RDF-savvy.
I would like us to consider also providing such option in Hydra.
It is there already in the form of adding operations to linked resources.
Does it mean that in UC#1 Entry point we would have to add statement </api/events> hydra:addMember </api/events> ?
I don't think that would be necessary because you already have the PUT
operation with appropriate type. And again, that predicate was purely for the example's sake. We could define one in hydra (akin hydra:search
) but it could also be any other API-specific link because it has limited semantics. What the client is actually interested in are the operations.
In case when that resource or template advertises more than one instances of hydra:Operation, how the client knows which of those operations to choose?
This is a good question but maybe a little vague. The real question is what are the client's requirements expectations. For starters, an operation already contains some information: the @type
(s), the expects
, the method
.
I wouldn't want to cram much more in the core specification. Any more elaborate metadata should IMO be outside of our scope and become some extension of Hydra Core
It seems like clients needs to follow those two steps
Actually, I was thinking of a single step albeit requiring recursion:
Find schema:CreateAction
in any recursively linked resource but only operation which expects: schema:Event
. In SPARQL you'd have two pattern:
`?operation rdf:type schema:CreateAction ;
hydra:expects schema:Event`
See how I drafted that in PR #143
IMO we should only rely statements using terms from Hydra vocab and something like schema.org actions and don't try to infer things from some particular choice of HTTP methods.
Ver much so! The HTTP method is just an implementation detail and we shouldn't encourage
What is this issue about at this point? What are the questions we need an answer for to resolve it?
After merging #143 now we have UC#5.1 Creating event with PUT
I think we can close this one and continue work in other issues, for exampe:
IriTemplate
@type
etc.
5. Creating new resources mentions creating resources with PUT
Solid also supports creating resources with PUT
In Vimeo API review we also find creating resources with PUT https://github.com/HydraCG/Specifications/issues/134#issuecomment-333393649
Last but not least, in open source project, which I currently work on, we also don't use POST and always create new resources with PUT relying on clients generating UUID ( actually https://github.com/ericelliott/cuid)
In use cases Entry Point we find definition of
schema:CreateAction
using HTTP POSTChallenge for HTTP PUT seems related to not having an
@id
for the resource which client needs to perform operation on. Most likely we would just have an URI Template, which I see something relevant discussed in #118 (Specifying operations on TemplatedLink objects) and touched in #100 (Describe/ specify how the target IRI for an hydra:operation is resolved).As for the
IriTemplateMapping
it seems to require for value ofhydra:property
anrdf:Property
withrdfs:range
UUID.