EntryPoint question
paul opened this issue · 13 comments
I'm having trouble figuring out the "correct" way to have an EntryPoint. The use-cases documentation for Entry Point 1.entry-point.md has an example where all the links are inside a "collection"
attribute. The Hydra Console demo app has instead the links as attributes at the root level. I assume that the use-case example is just newer, and top-level attributes is no longer the correct way to do it?
I think however, the newer "style" is not as useful because there's no human-friendly "name" by which to find the link. For example, if I'm scripting a client to go get all the Issues from the entry point, in the old style I just look for "issues" attribute. In the new style, though, if I want to do the same for Events, I'm not even sure what to look for. @id
is [http://example.com]/api/events
, and "title"
is a totally human "List of Events". There's the manages.object
attribute with "schema:Event"
, but I think this just says that this collection is a collection of Events. Ideally, I'd be able to tell my client "go look in the entry point document for "events"
(or "allEvents"
or something) and follow that URL". There doesn't seem to be any way to do that in the current scheme.
Sort of tangentially related, I also notice that the supportedOperations
for all the entry point items are always "POST". Is a "GET" operation on all URLs just always assumed to be possible? If so, how do I specify a resource to only support POST, and disallow GET?
@alien-mcl, might be worth adding a test showing how this works and include that also in the use case document. WDYT?
Sure thing - I'll try to set it up.
Still, I'm somehow confused with what @paul wrote in his issues
example. I think it's more related to how the JSON-LD payload is returned by the server. If it doesn't fit client's purpose it can always frame it so it has what the client needs.
BTW. I've reviewd history of that 1.entry-point.md and it seems that at the very beginning indeed entryPoint had one relation named collection
(somehow unfortunate in this case - it could be named events
) pointing to events.
After some changes this relation was extended with two more pointed resources. I feel that generic collection
name caused this disturbance. This property/relation name doesn't have any specific meaning and indeed it could be replaced with three relations named accordingly to what pointed resources are providing.
Oh, I see! So am I correct that the "collection"
attribute at the top-level wasn't meant to imply that it is a "collection" of entry-point links, but rather that the object contained within is itself a Collection
?
@alien-mcl I was also digging through the history of 1.entry-point.md
to figure out the intent, and it looks like whomever added the additional links was confused in the same way.
As for my "issues" example, let me be more specific. Lets say I'm writing a command-line tool that will import all Issues from the system described by the API and do something with them (save them to a local database, tweet about them, or publish them to another API). In a dumb CRUD API, I would write a client like get("http://example.com/issues").each { do_something_with_issue }
. In an enlightened Hypermedia API, however, I know that "/issues" can change at any point, so I'm better off starting at the entry point and following a link to get to the resource for "all issues". With the "Issue Tracker example API", I can have my script look for the attribute "http://www.markus-lanthaler.com/hydra/api-demo/vocab#EntryPoint/issues"
in the expanded JSONLD document. I could have my script do something like api("http://example.com/").dereference("EntryPoint/issues").each { ... }
In the EntryPoint given in the 1.entry-point.md, I'm not sure how to do that. I was mistakenly trying to "select" the Issues item from the "collection"
attribute, because of the misunderstanding I had. (As an aside, it would be extremely helpful if the Context for that EntryPoint was provided in that example.) How would I use that EntryPoint to "discover" the URL for the "events" (or in the example given, "events") resource?
We introduced the collection
property to link to related collections without requiring users to invent dedicated properties for each of them. The way I would see a client to work with this is something along the lines of:
client
.retrieve("http://example.com/")
.resources()
.ofType("hydra:Collection")
.where(resource => resource[hydra.manages][hydra.property] == rdf.type
&& resource[hydra.manages][hydra.object] == schema.Event);
.first()
.members()
.each( ... );
or, if you would like to make client a bit more aware of Hydra
client
.retrieve("http://example.com/")
.collections()
.thatManageMembersOfType(schema.Event)
.first()
.members()
.each( ... );
I see. So its expected that there will only ever be one resource in that collection that manages
schema.Event
s? I suppose that's the case, since things like "events created by me" and "events I've subscribed to" would be exposed as filters on that collection of events...
What does it look like if the EntryPoint links to something that's not a collection? "Invent a property", like you said?
As for the test mentioned, I think there is already such one. In the integration tests suite, file served as an entry point contains two collections exposed with examplevocab:events
and examplevocab:people
. The test obtains first one using client's API. Indeed we could introduce a helper i.e. collections
within the IHypermediaContainer
type exposed as hypermedia
property that would enable easier access to collections.
@alien-mcl I'm sorry, I'm not sure I'm following. That Heracles test EntryPoint has two links, both as top-level items. The EntryPoint in the use-case document has a "collection" top-level attribute as an array of collection items. The Heracles EntryPoint as the advantage of having a simple "key" that can be used to find the item ("examplevocab:Events"
). I guess that since JSON+LD, both those EntryPoint document structures are (or can be made to be) equivalent, but I'd really love to see the context document for the use-case EntryPoint.
I'm also not sure how to link to a resource that is not a collection in the use-case EntryPoint style, I think the docs could use an example of that.
I see. So its expected that there will only ever be one resource in that collection that
manages schema.Events
? I suppose that's the case, since things like "events created by me" and "events I've subscribed to" would be exposed as filters on that collection of events...
A collection with multiple manage blocks would be able to describe that:
"collection": [
{
"@id": "/events/createdByMe",
"@type": "Collection",
"manages": [{
"property": "rdf:type",
"object": "schema:Event"
}, {
"property": "createdBy",
"object": "/people/markus"
}]
}, {
"@id": "/events/IsubscribedTo",
"@type": "Collection",
"manages": [{
"property": "rdf:type",
"object": "schema:Event"
}, {
"subject": "/people/markus"
"property": "follows",
}]
}
What does it look like if the EntryPoint links to something that's not a collection? "Invent a property", like you said?
At the moment, yes. We actually didn't discuss this much so far.
I guess that since JSON+LD, both those EntryPoint document structures are (or can be made to be) >>equivalent
Indeed - doesn't really matter what is the name of the relation. Current reference client hooks up the @type
of the resource.
I'd really love to see the context document for the use-case EntryPoint.
Here it is. Probably it may be incorrect by means the use case uses collection
property and the context does not define a @vocab
.
What does it look like if the EntryPoint links to something that's not a collection?
There is a new unit test here that uses some (nested) resources with a custom link. Current implementation assumes that the relation must be marked with hydra:Link
in order to be discovered and exposed in the links
property of the client's API. Whether this requirements will preserve - time will show :)
Indeed - doesn't really matter what is the name of the relation. Current reference client hooks up the @type of the resource.
It does (unless there are other means such as manages
), as otherwise a client isn't able to choose among a set of collections.
Yes - manages
gives a hint to the client on the collection's semantics, but still, it is irrelevant from data model point of view. For client - the resource should be either typed as hydra:Collection
or the relation between the owner of the collection and the collection should inference that type (i.e. hydra:collection
of which I wasn't fully aware).