-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Describing operations and templates with SHACL #17
base: master
Are you sure you want to change the base?
Conversation
}, | ||
"@id": "/api", | ||
"@type": "hydra:ApiDocumentation", | ||
"requires": "http://www.w3.org/ns/hydra/shacl" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong opinion on the hydra:requires
term and its semantics.
Alternatively I thought hydra:uses
or hydra:imports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think better approach would be just to point to the SHACL's namespace, http://www.w3.org/ns/shacl#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe 🤔
As seen below, my intention was for http://www.w3.org/ns/hydra/shacl
to mean "SHACL extensions" and itself would become a namespace for additional terms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I remember now. I was thinking that maybe the requirements could be more fine-grained like
<> hydra:requires hashi:OperationExpects, hashi:IriTemplate
But coming back to my first answer still. The meaning is that "the API requires SHACL extension". Which is slightly more specific than just SHACL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced it's good direction. I think hydra should be extended in places where it does not provide any tools - replacing them is not a good move. It's better to create a separate spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think hydra should be extended in places where it does not provide any tools - replacing them is not a good move
What do you mean by that? I do propose a separate spec, auxiliary to core
-http://www.w3.org/ns/hydra/core#
+http://www.w3.org/ns/hydra/shacl#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like an idea where terms built in hydra would be replaced with some custom ones. In your example, hashi:IriTemplate
would probably replace hydra:IriTemplate
. I think it's not a good approach
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, no, I do not propose to replace anything.
I only wanted to propose a more fine-grained choice of which parts of the API are described with SHACL. hashi:IriTemplate
indeed may have been an unfortunate choice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hashi:IriTemplate
indeed may have been an unfortunate choice
Indeed - unfortunate. Could we come with a better one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, is that really necessary? It's not even mentioned in the pull request.
For the time being let's assume that only HASHI as a whole can be required, imported or used. However we choose.
"supportedOperation": { | ||
"@type": "schema:CreateAction", | ||
"method": "POST", | ||
"expects": ["mov:Movie", "mov:NewMovieShape"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeps "mov:Movie"
to keep backwards compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is kind of tricky. What does the set means: is it a union or alternative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Union, obviously. Nothing tricky. Read it like:
The operation expects
mov:Movie
which should conform tomov:NewMovieShape
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this very case it may be obvious, but in general it's not. Imagine a case when an operation expects i.e. good or service (which are in many cases disjoined classes). Intent was to tell the client that the operation (basket?) expects a resource of one of those types - resource being both of the classes would violate the vocabulary)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how this is relevant. Hydra Core would need to provide a way for alternatives just like OWL and SHACL do. Otherwise a set of objects is a union just like I would expect it anywhere else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's not directly related to possible extensions, but I expect questions in this (and similar) situations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise a set of objects is a union just like I would expect it anywhere else
It's not that straight forward. From pure RDF perspective it's a set of values and there is nothing supporting a statement a resource should be of all of the provided values. I'd actually prefer 'one of the possible values' rather than 'all of them'. I believe we need to specify it in the spec to avoid discrepancies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't make me look up deep in some RDF specs but I'm pretty sure that the semantics would be precisely that. If you have multiple objects of a property, then they form a set.
This is how OWL works and also how SHACL works. Hence the provide owl:oneOf
and sh:or
respectively to explicitly describe alternative choices without ambiguity.
If that is not enough, let's look at rdf:type
. <Karol> rdf:type schema:Person, foaf:Person
means that that resource has both of those types, not one of the possible values. Trying to apply different semantics to expects
would IMO violate the principle of least astonishment.
{ | ||
"@context": { | ||
"hydra": "http://www.w3.org/ns/hydra/core#", | ||
"requires": { "@id": "hydra:requires", "@type": "@id" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather reuse hydra:required
.
}, | ||
"@id": "/api", | ||
"@type": "hydra:ApiDocumentation", | ||
"requires": "http://www.w3.org/ns/hydra/shacl" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think better approach would be just to point to the SHACL's namespace, http://www.w3.org/ns/shacl#
"supportedOperation": { | ||
"@type": "schema:CreateAction", | ||
"method": "POST", | ||
"expects": ["mov:Movie", "mov:NewMovieShape"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is kind of tricky. What does the set means: is it a union or alternative?
+ "rdfs:label": "Search movies collection", | ||
+ "sh:property": [{ | ||
+ "sh:path": "schema:genre", | ||
+ "sh:name": "Genre", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe sh:name can be replaced with either hydra:title
or just `rdfs:label'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hydra:title
has no meaning in SHACL context
sh:name
is SHACL's method for annotating PropertyShape
I know it's weird but decided that way because rdfs:label
would effectively annotate the Shape where the intention is to indirectly annotate the property 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but which label client should use i.e. to build an UI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of what choice? There is only one label here (sh:name
) 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IriTemplate can accept hydra:title, which is prefered in context of hydra. If not provided, supported property can also have one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would consider a Shape as separate concerns.
So, the API describes its hypermedia with a Shape. That Shape can be then passed to a component which understand SHACL to build the UI for example and run validation. That SHACL-specific component would not be aware of Hydra though, hence I stick to only terms defined in SHACL.
The Shape is its own independent description which a Hydra client can take advantage of
+ }], | ||
+ "hashi:shape": { | ||
+ "@type": "sh:Shape", | ||
+ "rdfs:label": "Search movies collection", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think rdfs:description
fits better to the text provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite irrelevant but what would you have as the label then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something shorter I think. Just search
to feed a button?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is rather minuscule
"property": "schema:genre" | ||
- }] | ||
+ }], | ||
+ "hashi:shape": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this relation. Resource <movies>
is in relation <hashi:shape>
with some blank node resource. How does it tell the client that values for schema:genre
can be used from the given set? What if schema:genre
defines already a set somewhere else (i.e. API documentation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resource
<movies>
is in relation<hashi:shape>
Did I get the formatting wrong? It's the IriTemplate
which has that relation
some blank node resource
sh:Shape
🙄
How does it tell the client that values for
schema:genre
can be used from the given set?
In turtle you would have
<movies> hydra:search [
hydra:mapping [
hydra:property schema:genre
] ;
hashi:shape [
sh:property [
sh:path schema:genre ;
sh:in ( "Comedy" "Drama" )
]
]
] .
To populate the template a resource is constructed which has the schema:genre
property.
hydra:mapping
informs the client how to map it to the template variables
hashi:shape
provides information about the resource constraints
What if
schema:genre
defines already a set somewhere else (i.e. API documentation).
You're looking for something which is not there. I know not of an alternative way to define such a set other than SHACL. And even so, I think that those SHACL descriptions would be applied locally and trump one defined elsewhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that those SHACL descriptions would be applied locally and trump one defined elsewhere
I'm not sure I understand. I believe these kind of descriptions could be applied both on API documentation and resource level. I imagine situation where an API documentation says that property schema:genre
in shape Movie
can accept any value taken from the list. But a resource description gives another list. How those are related to each other?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, it's a little bit out of scope of this constrained example. Sure, the sh:property
could somehow reference a shared list of elements, defined in the API Documentation. Sounds like a good idea.
In the first version of an actual HASHI
spec I would also define a way to refer to a hydra:Collection
so that the choices can be loaded from the API itself.
Either case however goes beyond what I want to propose here, which is extending the IRI Template definition with a Shape by the use of hashi:shape
property
In this PR I propose how SHACL Shapes can augment the API descriptions
Of operation payload, by replacing the value of
hydra:expects
with a Shape. Thehydra:returns
annotation could also be extended with a Shape by analogy but I have not considered such a scenario yet.Of IRI Templates by attaching Shape to the
IriTemplate
and without changing anything else about the Core usage.Both proposed usages on SHACL with Hydra Core do not replace any terms and only extend the standard descriptions as we have them now. This way a client which does not understand SHACL will still be able to use the semantics of Hydra Core.