Closed elf-pavlik closed 6 years ago
In https://www.w3.org/TR/ldp/#ldpc-HTTP_DELETE spec mandate that LDP server
5.2.5.1 When a contained LDPR is deleted, the LDPC server MUST also remove the corresponding containment triple, which has the effect of removing the deleted LDPR from the containing LDPC.
If hydra client can not rely on hydra server to remove 'containment triple', it may require client to always take that responsibility. Having operations like AddMemberOperation
and RemoveMemberOperation
would allow client to do it. Then we also may need to address a case where client issues RemoveMemberOperation
but doesn't DELETE the resource (eg. /events/42
), which would lead to collection /events
not referencing any more /events/42
as its member.
Okay, upon reading the excerpt from LDP I must admit that I was wrong in the quote above.
When you DELETE /events/42
you definitely should remove the /events hydra:member /events/42
. This is what you were asking about right?
Not sure what I was thinking anymore 😉
This works (most of the time at least) as long as a single server or organization controls both things. If I have a service that collects bookmarks for instance, it won't be able to delete the URL in the collection if the referenced blog post got deleted. Perhaps we should have a specialized Delete operation. Something like DeleteAndRemoveMember.
LDP also mandates for ldp:container
to add containment triple on POST
https://www.w3.org/TR/ldp/#h-ldpc-http_post
5.2.3.2 When a successful HTTP POST request to a LDPC results in the creation of a LDPR, a containment triple MUST be added to the state of the LDPC whose subject is the LDPC URI, whose predicate is ldp:contains and whose object is the URI for the newly created document (LDPR). Other triples may be added as well. The newly created LDPR appears as a contained resource of the LDPC until the newly created document is deleted or removed by other methods.
IMO we need to handle those two cases POST & DELETE together in hydra:Collection
which acts like ldp:Container
(supports creating new resources which it will contain). hydra:Collection which just references, but not *contains*, other resources seems to work more like regular
ldp:Resource` and creating & deleting resources happens independent from linking/unlinking them to the collection.
Perhaps we should have a specialized Delete operation. Something like DeleteAndRemoveMember.
Currently operations stay 'attached' to a single resource. DeleteAndRemoveMember
seems to affect two resources:
I think it may help if we think of Hydra API as an interface to an RDF dataset, which also provides other interfaces - SPARQL, Triple Pattern Fragments etc. For example if we want to add a triple to the dataset via SPARQL 1.1 Update
BASE <https://media.example/>
PREFIX sor: <http://purl.org/net/soron/>
INSERT DATA { </users/elfpavlik> sor:likes </videos/144522067> . } }
requesting Triple Pattern Fragment
{
"subject": "https://media.example/users/elfpavlik",
"predicate": "http://purl.org/net/soron/likes"
}
will include that added tripple. In similar way when we remove that triple with DELETE DATA
the very same TPF will automatically not include it any more. In case of TPF we don't have to worry about modifying the resource denoted by particular TPF IRI since that resource represent a result of query on the dataset which has TPF interface.
In example from https://github.com/HydraCG/Specifications/issues/134#issuecomment-333408225 we have two related relationships going on.
</users/elfpavlik> sor:likes </videos/144522067>.
(subject & object IRIs both denote Things)</users/elfpavlik/likes> hydra:member </videos/144522067> .
(subject IRIs denotes API specific Resources and object IRI denotes a Thing)The manages
block
"manages": {
"subject": "/users/elfpavlik",
"property": "sor:likes"
}
Focuses on relationship between Things, while member
on relationships between API specific resource (instance of hydra:Collection
) and a thing. AFAIK in LDP we would have </users/elfpavlik/likes> ldp:contains </users/elfpavlik/likes/144522067>.
so relation between two API specific resources.
Let's try to make a dataset from snippets in our use cases and expose it with 3 interfaces
@RubenVerborgh do you have some insights to share on how you see Hydra and LDF working together to expose the same dataset?
As we see in Vimeo example, it does behave similar to having a dataset exposed by API.
- in case of likes -
PUT /users/{user_id}/likes/{video_id}
server will update both
/users/{user_id}/likes
/videos/{video_id}/likes
- in case of channels subscriptions -
PUT /users/{user_id}/channels/{channel_id}
server will update both/users/{user_id}/channels
/channels/{channel_id}/users
Creating or Deleting a resource gets reflected in two different collection, where only one of them would have ldp:contains
relationship (guessing by looking at IRI as not opaque identifiers)
Looks like that #137, #134 and #141 are somehow related to each other. Can we somehow join those as I'm not sure on where to reply :)
I see #141 as more general while it uses the same use case. How about focusing on #134 first then picking up this particular aspect here? If we go with LINK & UNLINK and collections as generated views we may find this issue here not relevant any more. I'll close this one here for now and we can always reopen it if needed!
For completeness:
do you have some insights to share on how you see Hydra and LDF working together to expose the same dataset?
I guess this is more of a question of doing the same things different ways in Hydra. The TPF interface uses Hydra to explain "you can filter by triple pattern". If there are multiple ways to express this, we need to discuss this, and perhaps eliminate.
Capturing from #134