Skip to content

Instantly share code, notes, and snippets.

@JeniT
Created June 14, 2012 01:40
Show Gist options
  • Save JeniT/2927644 to your computer and use it in GitHub Desktop.
Save JeniT/2927644 to your computer and use it in GitHub Desktop.
Possible way to provide POSTable URI in RDF
<http://www.amazon.com/gp/product/B000QECL4I>
eg:reviews <http://www.amazon.com/product-reviews/B000QECL4I> ;
eg:order "http://www.amazon.com/gp/product/B000QECL4I{?copies}" ;
.
and then the definition of eg:reviews would say "the object of this property
provides reviews of the subject of this property" and the definition of
eg:order would say "POST to the URI generated by expanding the URI template
value of this property where the copies variable is the number of copies to
be ordered"
dunno on question of whether URI template should have its own datatype
@ldodds
Copy link

ldodds commented Jun 14, 2012

An alternate approach to this is to model the service that does the ordering, and then relate a resource to that service. This has the advantage of describing more of the interaction, i.e. the HTTP method, acceptable media types and parameters. This basically mirrors HTML forms into RDF. This is what Mark Baker suggested as part of RDF Forms.

E.g.

<http://www.amazon.com/gp/product/B000QECL4I>
  ex:Product;
  ex:reviews <http://www.amazon.com/product-reviews/B000QECL4I> ;
  ex:order <http://example.org/order-service> ;

<http://example.org/order-service>
  rdf:type ex:Service, ex:OrderService;
  ex:method "POST";
  ex:mediaType "application/x-www-form-urlencoded";
  ex:param [
    rdfs:label "item";
    ex:type ex:Product;
  ];
  ex:param [
    rdfs:label "copies";
    ex:type xsd:integer;
  ];

We can do a GET on the order service to retrieve a description of how to interact with it. Clients can implement support for the generic form interaction. This reduces the amount of specification needed for each new property and provides some hope that a client could still offer some useful behaviour for a newly encountered service (e.g. rendering a form).

Its worth noting that we currently do refer to services in Linked Data. VoID allows us to refer to a sparql endpoint, an item description service or a search endpoint as URIs associated with a dataset. But it doesn't say how to interact with them, clients have instead implemented operational semantics for each of the specific predicates. This approach can cleanly extend that.

I had hoped that SPARQL Service Description might help achieve that for sparql endpoints, but the WG has avoided specifying any relationship to VoID. It has also unfortunately decided to avoid describing the endpoint service explicitly, instead using a "endpoint" property to refer to its URL; which is a mistake I think. (See example at http://www.w3.org/TR/sparql11-service-description/#example)

@ldodds
Copy link

ldodds commented Jun 14, 2012

@dret re: "the RDF might be a nice starting point for generating documentation, if it contains human-readable descriptions, but that would be about it, right"

Well if there's a richer description of the service, as I outlined in my other comment, then we can do more than render behaviour, we could query for services that can offer particular types of interaction, or can operate on particular types of resources (as described by input parameters). E.g: find me a list of annotation or review services; find me a list of services that operate on foaf:Person resources.

@JeniT
Copy link
Author

JeniT commented Jun 14, 2012

@ldodds, thanks :)

Having slept on it, my thought was that the right place to define the operational semantics of a given URI (eg whether and what you can POST to it) was through the class of a resource rather than on the property itself, but of course that you could get to the relevant class from the range/domain of the property. So I think a pattern like this.

A vocabulary author publishes:

ex:order a rdf:Property ;
  rdfs:comment "A resource used to order a product."
  rdfs:domain ex:Product ;
  rdfs:range ex:OrderingResource ;
  .

ex:OrderingResource a rdfs:Class ;
  rdfs:comment "A resource that can be POSTed to to order something; the POSTed details of the order must be provided through an RDF graph that includes ex:Order individuals" ;
  rdfs:subTypeOf rest:POSTableResource ;
  .

Then Amazon would publish:

<http://www.amazon.com/gp/product/B000QECL4I>
  ex:Product ;
  ex:reviews <http://www.amazon.com/product-reviews/B000QECL4I> ;
  ex:order <http://www.amazon.com/order> ;
  .

<http://www.amazon.com/order>
  a ex:OrderingResource ;
  rest:acceptable "application/rdf+xml" , "text/turtle" ;
  .

and a Linked Data Platform spec would define rest:POSTableResource as "a resource that can be POSTed to" and rest:acceptable as "a media type that can be accepted in a POST or PUT to a given POSTable or PUTtable resource". Or something.

Through OWL, the ex: vocabulary could define additional constraints on ex:OrderingResource such as that it must have at least one value for rest:acceptable, or that one of the values must be "application/rdf+xml" or whatever.

When it comes to parameters, I think the Linked Data Platform WG needs to explore the pros and cons of a URI template approach vs a service description approach: it's certainly not obvious to me whether one or other approach is better, or whether they can work together somehow. Perhaps if the URI were parameterised rather than POSTing a graph, an approach like this might work:

<http://www.amazon.com/order>
  rdf:type ex:OrderingResource ;
  rest:uriPattern "http://www.amazon.com/order{?copies}" ;
  .

ex:OrderingResource
  rest:uriParam [
    a rest:URIparameter ;
    rdfs:label "copies" ;
    rdfs:comment "The number of copies to be ordered." ;
  ] ;
  .

I'm not sure. It needs some thinking about to what extent this is useful for auto-discovery, generated documentation, generated code and so on, and to what extent applications will simply hard-code knowledge about vocabularies that they are interested in. My feeling is that we should learn from experience from the XML stack (WSDL, UDDI etc) and not over-engineer.

@ldodds
Copy link

ldodds commented Jun 14, 2012 via email

@ldodds
Copy link

ldodds commented Jun 14, 2012

btw, with a URI template approach unless you want to build all of the operational semantics into the property (e.g. definitions of the variables, http method, media types, etc) then you need to describe at least some of the service.

As a data point, the Google Discovery API uses URI templates to aid URL construction, but still has definitions of the parameters including type indications:

https://developers.google.com/discovery/v1/using#build-compose

@JeniT
Copy link
Author

JeniT commented Jun 14, 2012

@dret regarding media types: I just want to make sure that you're not suggesting something like inventing application/order+rdf+xml or application/order+rdfs+foaf+dct+rdf+xml or something as you start using more vocabularies in your RDF...

Of course the way in which some data is processed needs to be "defined by the media type", but that only means that there should be a follow-your-nose method of working out how to process the data based on the media type. In the case of RDF media types, the follow-your-nose method is that the media type (eg application/rdf+xml or text/turtle) says how to build an RDF graph and then indicates how that is interpreted at an RDF level by reference to the RDF specs. The RDF specs then say that the semantics (operational/interactional or otherwise) of a property/class etc is defined by the RDF assertions about that property/class (ie by the vocabulary, which you can discover by resolving the URI for the property/class).

So you don't need to have separate media types for each combination of vocabularies used in a particular message: you just say that the message is of an RDF media type and locating the definition of the meaning of that particular message then follows naturally.

What's interesting as you know is what level of standardisation (classes/properties that can be used as superclasses/properties or to annotate classes/properties) you need to get useful generic behaviour (eg having a class for "Collection" that implies operational semantics similar to that provided in Atom feeds)...

@dret
Copy link

dret commented Jun 14, 2012

@JeniT what i am not understanding is how that approach could possibly work in scenarios beyond reading data. i see it working in reading, where like in XML you just GET application/xml and hope for the best, searching for namespaces and either finding stuff you understand or just stop when there's nothing. but for scenarios beyond read, there must be a way to communicate expectations, and that's where media types play a crucial role. how would i know what i am supposed to PUT/POST somewhere? the web's flavor of REST tells you that this kind of expectation is communicated via HTTP, so that clients know what to transfer. state transfer means that there is an agreement between peers what to transfer in the context of an application scenario (which is covered by one or more media types), and how the flow of state between clients and servers works. you can always add on at runtime if that's within the design space of the application ("profile" is where we're trying to make this explicit as well), but you need to set the baseline (and make that visible at the protocol level) of what the state transfer has to look like to make the application work.

@JeniT
Copy link
Author

JeniT commented Jun 14, 2012

@dret I really don't understand what you're trying to say I'm afraid. Can you outline (preferably with this example) what you think would work, or is needed?

@dret
Copy link

dret commented Jun 14, 2012

i'll try to keep it short and you can let me know where i should elaborate. i am making up an example, hoping it connects the dots.

  • let's say a service has an "order" link where the client is supposed to submit payment information (i.e., transfer payment state from client to server).
  • there's an expectation on the server side what a client POSTs, it must follow the payment schema supported by the server.
  • let's assume the server also supports payment according to three other payment schemes, which allow payment state to be transferred as well, two of them XML-based, one RDF-based.
  • the server should indicate what is acceptable as payment through the "order" link by using the media types of the payment protocols (similar to AtomPub's <accept> http://tools.ietf.org/html/rfc5023#section-8.3.4).
  • if a client attempts to use an unsupported payment protocol (read: it submits something not according to the payment schemas acceptable by the server), the server responds with a 415, repeating the accepted media types in the HTTP response (ideally).

media types are necessary to communicate expectations wrt state transfers (they answer the simple question: "how do you represent state, and how do you find the interaction links"), and application/rdf has the same problem application/xml has: it does not identify a model, it identifies a metamodel. it took a while for the XML and JSON communities to start minting meaningful media types instead of the generic ones, but now we're getting there. we have to expose a service's interaction semantics within the fabric of the web, not in a framework that requires clients to reach within specific representations.

@dret
Copy link

dret commented Jun 14, 2012

@JeniT, i am just repeating my question here, because i really would like to see how your scenario would work. you say that "you don't need to have separate media types for each combination of vocabularies used in a particular message: you just say that the message is of an RDF media type and locating the definition of the meaning of that particular message then follows naturally." once again, for GETting RDF that might work, but how does that work when a client is supposed to PUT something? the client has application state (a rather abstract "order intent") and needs to get that to the server. representing that order intent needs a framework where the client knows which order representation is acceptable to the server. there could be various order representations in RDF that a client knows about (because it may be capable of talking to different services, for example), so if the "order" link simply is described by "send me some RDF", how does the client decide which order vocabulary to use? please explain to me how you see this working, i really want to understand this part of the puzzle.

@JeniT
Copy link
Author

JeniT commented Jun 15, 2012

@dret I think I see the point you're making: you need to express what you can POST or PUT to a given URI using some method that makes those restrictions discoverable by HTTP machinery. I've looked at HTTPbis and I can't immediately see where that machinery is. You imply that there's something like an "Accept-Content-Types" header that enables a server to list acceptable content types for POST/PUTting, but I can't see it. Can you point me at it or if there isn't one, explain how a server that supported POSTing using a particular +json media type would express that constraint (I guess in response to an OPTIONS request on the URI)?

@dret
Copy link

dret commented Jun 15, 2012

i'm afraid you're right that for a reason i cannot think of right now, Accept is a request header only, which means you could put the list in a 415 error document, but that would be convention and not the standard. so no, there is no machinery communicating the list of acceptable media types back to the client in case of an error. but looking at the first part of the question, how to even know what to submit, there is a way how that state is transferred to the client (here's the book info, there's the order link, and here's what to POST to it as payment info), and my question still is how you would communicate that expectation to the client. the client needs to know what it is expected to submit, so just telling it "submit RDF" is not sufficient.
asking the same question in a different way: in existing RDF services, how does that work? does a client just "know" what it is supposed to POST/PUT to a given URI if it wants to interact with the service in the context of an application? how does it acquire that knowledge? in media types, that knowledge would be coupled to the link relation, either implicitly (submit something using this vocabulary when traversing such a link), or explicitly (often using link/@type or link/@accept attributes in XML vocabularies). this allows clients to choose according to their capabilities and preferences, if servers provide alternatives, and those alternatives are communicated through media types. new capabilities may show up when a server starts supporting additional interactions, but clients often need to be updated (learning about the new media types) to be able to take advantage of these new capabilities.

@ldodds
Copy link

ldodds commented Jun 15, 2012 via email

@dret
Copy link

dret commented Jun 16, 2012 via email

@JeniT
Copy link
Author

JeniT commented Jun 16, 2012 via email

@dret
Copy link

dret commented Jun 18, 2012 via email

@aharth
Copy link

aharth commented Jul 10, 2012

Hi,

why not use SPARQL (or rather, graph patterns) to describe inputs, outputs and relation between input and output? Most of the current approaches on http://linkedservices.org/ use that type of description.

HATEOAS URIs could just be embedded into the RDF that's returned.

Best regards,
Andreas.

@cygri
Copy link

cygri commented Nov 8, 2012

Interesting discussion! Thanks @JeniT, @dret and @ldodds! And no, I'm still not convinced that there's value in defining new media types for every application. That's an anti-pattern needed to cope with formats that don't have hypermedia capabilities and can't be extended in a standard way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment