Restful semantic web services

Here is my first stab at an outline for what a restful semantic web services would look like.

Let me start with the obvious. Imagine we have an example shopping service, at http://shop.eg/, which sells books. Clearly we would want URLs for every book that we wish to buy, with RDF representations at the given URL. As I find RDF/XML hard to read and write, I'll show the N3 representations. So to take a concrete example, let us imagine our example shopping service selling the book "RESTful Web Services" at the URL http://shop.eg/books/isbn/0596529260 . If we do an HTTP GET on that URL we could receive the following representation:


@prefix : <http://books.eg/ns#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix shop: <http://shopping.eg/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix currency: <http://bank.eg/currencies#> .


<#theBook> a shop:Book, shop:Product;
   dc:title "Restful Web Services"@en ;
   dc:creator [ a foaf:Person; foaf:name "Sam Ruby"],
             [ a foaf:Person; foaf:name "Leonard Richardson"] ;
   dc:contributor [ a foaf:Person; foaf:name "David Heinemeier Hansson" ];
   dc:publisher <http://www.oreilly.com/>;
   dct:created "08-07-2007T"\^\^xsd:dateTime;
   dc:description """This is the first book that applies the REST design philosophy to real web services. It sets 
 down the best practices you need to  make your design a success, and the techniques you need to turn your 
 design into working code. You can harness the power of the Web for programmable applications: you just 
 have to work with the Web instead of against it. This book shows you how."""@en;
   shop:price "26.39"\^\^currency:dollars;
   dc:subject </category/computing>, </category/computing/web>, </category/computing/web/rest>, 
                   </category/computing/architecture>,</category/computing/architecture/REST>, </category/computing/howto> .


So we can easily imagine a page like this for every product. These pages can be accessible either by browsing the categories pages, querying a SPARQL endpoint, among many other ways. It should be very easy to generate such representations for a web site. All it requires is to build up an ontology of products - which the shop already has available, if only for the purposes of building inventories - and tie these to the database using a tool such as D2RQ, or a combination of JSR311 and @rdf annotations (see so(m)mer).

Now what is missing is a way to let the browser know what it can do with this product. The simplest possible way of doing this would be to create a specialized relation for that web service to POST some information to a Cart resource, describing the item to be added to the cart. Perhaps something like:

<#theBook> shop:addToCart <http://shop.eg/cart/> .

This relation would just mean that one has to POST the url to the cart, to have it added there. The cart itself may then have a shop:buy relation to some resource, which by convention the user agent would need to send a credit card, expiration date, and other information to.
This means that one would have to define a number of RDF relationships, for every type of action one could do in a shop (and later on the web), and explain the types of messages to be sent to the endpoint, and what their consequences are. This is simple but it does not seem very extensible. What if one wants to buy the hard copy version of the book, or 10 items of the book? The hard copy version of course could have its own URL, and so it may be as simple as placing the buy relation on that page. But is this going to work with PCs where one can add and remove a huge number of pieces. I remember Steve Jobs being proud of the huge number of different configurations one could buy his desktop systems with, well over 100 thousand different configurations I remember. This could make it quite difficult to navigate a store, if one is not careful.

On the current web this is dealt with by using html forms, which can allow the user to choose between a large number of variables, by selecting check boxes, combo boxes, drop down menues and more, and then POST a representation to a collection, and thereby create a new action, such as adding the product to the cart, or buying it. The person browsing the site knows what the action does, because it is usually written out in a natural language, in a way that makes it quite obvious to a human being. The person then does that action because he desires to do so, because he wishes his desires to be fulfilled. Now this may seem very simple, but just consider the innumerable types of actions that we can fulfill using the very simple tool of html forms: we can add things to a virtual cart, buy things, comment about things, search for things, organise a meeting, etc, etc.... So forms can be seen both as shortcuts to navigate to a large number of different resources, and to create new resources (usually best done with POST).
If we want software agents to do such tasks for us we need both to have something like a machine understandable form, and some way of specifying what the action of POSTing the form will have on the world. So we need to find a way to do what the web does in a more clearly specified way, so that even machines, or simple user agents can understand it. Let's look at each one:

  • Forms are ways of asking the user to bind results to variables
  • the variables can the be used to build something, such as a URL, or a message.
  • The form then specifies the type of action to do with the constructed message, such as a GET, POST, PUT, etc...
  • The human readable text explains what the result of the action is, and what the meaning of each of the fields are.

Now what semantic technology binds variables to values? Which one asks questions? SPARQL comes immediately to mind. Seeing this and remembering a well known motto of sales people "Satisfy the customer every desire" a very general but conceptually simple solution to this problem occurred to me. It may seem a little weird at first (and perhaps it will continue to seem weird) but I thought it is elegant enough to be used as a starting point. The idea is really simple: the representation returned by the book resource will specify a collection end point to POST RDF too, and it will specify what to POST back by sending a SPARQL query in the representation. It will then be up to the software agent reading the representation to answer the query if he wishes a certain type of action to occur. If he understand the query he will be able to answer, if he does not, there should be no results. He need not do anything with the query at all.

The following is the first thing that occurred to me. The details are less important than the principle of thinking of forms as asking the client a question.

PREFIX shop: <http://shopping.eg/ns#>
PREFIX bdi: <http://intentionality.eg/ns#>
CONSTRUCT {
     ?mycart a shop:Cart ;
             shop:contains [ a shop:LineItem;
                               shop:SKU <http://shop.eg/books/isbn/0596529260#theBook> ;
                               shop:quantity ?q ;
                             ]  .
}  WHERE {
       ?mycart a shop:Cart ;
               shop:for ?me ;
               shop:ownedBy <http://shop.eg/>.
       GRAPH ?desire {
               ?mycart shop:contains
                            [ a shop:LineItem;
                               shop:SKU <http://shop.eg/books/isbn/0596529260#theBook> ;
                               shop:quantity ?q ;
                            ]  .

       }
       ?desire bdi:of ?me .
       ?desire bdi:fulfillby "2007-07-30T..."\^\^xsd:dateTime .
}

So this is saying quite simply: Find out if you want to have your shopping cart filled up with a number of this book. The user agent (the equivalent of the web browser) asks its data store the given SPARQL query. It asks itself whether it desires to add a number of books to its shopping cart, and if it wishes that desire to be fulfulled by a certain time. If the agent does not understand the relations in the query, then the CONSTRUCT clause will return an empty graph. If it does understand it, and the query returns a result, then it is because it wished the action to take place. The constructed graph may be something like:

@prefix shop: <http://shopping.eg/ns#>
 <http://shop.eg/cart/bblfish/> a shop:Cart ;
             shop:contains [ a shop:LineItem;
                               shop:SKU <http://shop.eg/books/isbn/0596529260#theBook> ;
                               shop:quantity 2 ;
                             ]  .

This can then be POSTed to the collection end point http://shop.eg/cart/, with the result of adding two instances of the book to the cart. Presumably the cart would return a graph with the above relations in it plus another SPARQL query explaining how to buy the items in the cart.

So the full RDF for the book page would look something like this:

@prefix : <http://books.eg/ns#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix shop: <http://shopping.eg/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix currency: <http://bank.eg/currencies#> .


<#theBook> a shop:Book, shop:Product;
   dc:title "Restful Web Services"@en ;
   dc:creator [ a foaf:Person; foaf:name "Sam Ruby"],
             [ a foaf:Person; foaf:name "Leonard Richardson"] ;
   dc:contributor [ a foaf:Person; foaf:name "David Heinemeier Hansson" ];
   dc:publisher <http://www.oreilly.com/>;
   dct:created "08-07-2007T"\^\^xsd:dateTime;
   dc:description """This is the first book that applies the REST design philosophy to real web services. It sets 
 down the best practices you need to make your design a success, and the techniques you need to turn your
  design into working code. You can harness the power of the Web for  programmable applications: you just 
 have to work with the Web instead of against it. This book shows you how."""@en;
   shop:price "26.39"\^\^currency:dollars;
   dc:subject </category/computing>, </category/computing/web>, </category/computing/web/rest>, 
                      </category/computing/architecture>,</category/computing/architecture/REST>,</category/computing/howto>;
   shop:addToCart [ a Post;
                    shop:collection <http://shop.eg/cart/>;
                    shop:query """
PREFIX shop: <http://shopping.eg/ns#>
PREFIX bdi: <http://intentionality.eg/ns#>
CONSTRUCT {
     ?mycart a shop:Cart ;
             shop:contains [ a shop:LineItem;
                               shop:SKU <http://shop.eg/books/isbn/0596529260#theBook> ;
                               shop:quantity ?q ;
                             ]  .
}  WHERE {
       ?mycart a shop:Cart ;
               shop:for ?me ;
               shop:ownedBy <http://shop.eg/>.
       GRAPH ?desire {
               ?mycart shop:contains
                            [ a shop:LineItem;
                               shop:SKU <http://shop.eg/books/isbn/0596529260#theBook> ;
                               shop:quantity ?q ;
                            ]  .

       }
       ?desire bdi:of ?me .
       ?desire bdi:fulfillby "2007-07-30T..."\^\^xsd:dateTime .
}"""
                  ] .

So there are quite a few things to tie up here, but it seems we have the key elements here:

  • RESTful web services: we use GET and POST the way they are meant to be used,
  • Resource Oriented Architecture: each shoppable item has its resource, that can return a representation
  • the well known motto "hypermedia is the engine of application state": each URL is dereferenceable to further representations. Each page of a containing a buyable item describes how one can proceed to the next step to buy the product. In this case the SPARQL query returns a graph to be POSTed to a given url.
  • with the clarity of the Semantic framework thrown in too. Ie. We can proove certain things about the statements made, which is very helpful in bringing clarity to a vocabulary. Understanding the consequences of what is said is part and parcel of understanding itself.
Have I reached buzzword compliance yet? :-)

Notes

From discussions around the net (on #swig for example) I was made aware of certain problems.

  • SPARQL is a little powerful, and it may seem to give too much leverage to the service, who could ask all kinds of questions of the user agent, such as the SPARQL equivalent of "What is your bank account number". Possible answers may be:
    • Of course a user agent that does shopping automatically on the web, is going to have to be ready for all kinds of misuses, so whatever is done, this type of problem is going to crop up. Servers also need to protect themselves from probing questions by user agents. So this is something that both sides will need to look at.
    • Forms are pretty powerful too. Are forms really so different from queries? They can ask you for a credit card number, your date of birth, the name of your friends, your sexual inclinations, ... What can web formst not ask you?
  • SPARQL is a language that does a couple of things going for it: it has a way of binding variables to a message, and it builds on the solid semantic web structure. But there may be other ways of doing the same thing. OWL-S also uses rdf to describe actions, create a way to bing answers to messages, and descibe the preconditions and postconditions of actions. It even uses the proposed standard of Semantic Web Rules Language SWRL. As there seems to be a strong relation between SPARQL and a rule language (one can think of a SPARQL query as a rule), it may be that part of the interest in this solution is simply the same reason SWRL emerged in OWL-S. OWL-S has a binding to SOAP and none to a RESTful web service. As I have a poor grasp of SOAP I find that difficult to understand. Perhaps a binding to a more restful web service such as the one proposed here would make it more amenable to a wider public.

Comments:

Nice one. There's an application I've had in my todo list way too long now (recently shifted over as something to do with the Talis kit) - an RDF/HTTP(/SPARQL) version of the J2EE Pet Shop. This looks like a good start. Do you know of any Web 1.0+ style shops based on RDF..?

Posted by Danny on July 03, 2007 at 09:43 AM CEST #

Well, we need to get together on the J2EE Pet Shop. I was thinking of doing just that myself. That would make for a very good demo :-)

I don't know of any Web 1.0 shops based on RDF no, but that does not mean there are none....

Posted by Henry Story on July 03, 2007 at 10:28 AM CEST #

I just found a very interesting article (via Danny) entitled "SPARQL as an expression language for OWL-S" which takes on many of the themes explored here. This is clearly a serious research article, with lots of good pointers, which I am happy to see is confirming my intuitions.

OWL-S is not conceptually very difficult to understand but it is - like most such technical papers - a little tedious to read. Everytime I come across a new XML vocabulary, my eyes glaze over, so it is really nice to have the expression language replaces with something much easier to understand like SPARQL.

Now the worse part of OWL-S is that the only grounding currently is a SOAP grounding. This makes it nearly impossible for a normal human being with a life to get to understand OWL-S. As I understand the grounding is needed to specify the relation between the ontology and the messages to pass to the server. I think this blog post of mine goes further than what is proposes in the article under consideration, in that I am proposing to get rid of the binding to SOAP, and use RDF messages generated by a SPARQL query instead.

Both of us are using intentional semantics, and using SPARQL to query the user agent... So we may just be onto something here... I need to re-read this article carefully.

Posted by Henry Story on July 16, 2007 at 04:20 PM CEST #

Hello Henry, this seems really interesting, in fact this is just what i was looking for, I'm planning of doing my thesis on implementing SOA using RESTful semantic web services i'm still researching but i think i may be on my way after reading this, it took me a while to understand but it seems this approach using SPARQL is just what RESTful services need, at least it doesn't break the simplicity of REST and it is very easy to understand (it took me a while but i am a new at this), i didn't get the whole OWL-S thing probably because of my lack of fundamental knowledge on the matter, but i am very impressed by your approach....it would be really nice if i get the chance to explore this or any other similar approach in my thesis. Regards

Posted by Roger Marin on July 31, 2007 at 09:06 PM CEST #

Apparently, some people have similar thoughts:

http://simplewebservices.org/index.php?title=Shopping

Posted by Jiri Kopsa on September 23, 2007 at 05:47 PM CEST #

Yes, I was/am on the simplewebservices mailing list. It got into tiring conversation of rdf versus xml at the beginning. Also the rdf vocabulary used there is way to low level: it is not because the service is RESTful, that one has to use HTTP vocabulary relations.

But the main idea is exactly right. I am going to do a little demo application very soon that same area...

Posted by Henry Story on September 24, 2007 at 02:35 AM CEST #

I incidentally came across this page, which I find quite interesting. I'm the author of the paper "SPARQL as an expression language for OWL-S" cited above. I've further developed these ideas in my PhD thesis, where I discuss also the use of SPARQL for defining preconditions and effects of RESTful Web services. Is someone working on this topic? I would be happy to discuss it.

Posted by Marco Sbodio on June 30, 2009 at 01:16 AM CEST #

Post a Comment:
Comments are closed for this entry.
About

bblfish

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today