Integration with SHACL

From Hydra Community Group

Introduction

Holger Knublauch has proposed a possible integration path between Hydra and SHACL. Basically, the idea is to make hydra:Class a subclass of sh:Shape.

Hydra uses hydra:Class in several places. One usage is to describe possible request bodies for PUT and POST operations - both in a general ApiDocumentation (hydra:supportedOperation), but also ad-hoc within responses that want to state that a related resource allows a particular operation right now (hydra:operation).

Event Platform API

Let us assume an event platform API wants to describe that its /events resource accepts POST request bodies to create event entries similar to the one below.

   // an acceptable POST request body
   {
     "@context": "http://schema.org",
     "@type": "MusicEvent",
     "name": "Shostakovich Leningrad",
     "startDate": "2016-04-21T20:00"
     "location": {
       "@type": "MusicVenue",
       "name": "Chicago Symphony Center",
       "address": {
         "streetAddress" : "220 S. Michigan Ave",
         "addressLocality" : "Chicago",
         "addressRegion" : "IL",
         "addressCountry": "USA"
       }
     }
     "eventStatus": "EventScheduled"
   }

What makes things interesting is:

  • the usage of a vocabulary which is not under control of the service (schema.org). Can we express restrictions on a resource of an externally described class which only apply locally - not only local to an API, but local to a specific expected response?
  • the contextual or "nested" schema:name Attribute. We need to say that we expect both a name for the music event *and* the location.
  • the dual type of schema:location - it could be a Place or a PostalAddress. Examples on schema.org show that even a plain String might occur.
  • the subclassing for the event type: the service wants to say that it accepts many kinds of events, not just MusicEvent. It is however not accepting a DeliveryEvent or a UserInteraction, because these Events are not the kind of Event the platform wants to publish.
  • the platform also expects the fixed value "EventScheduled" in a POST, initially it does not allow "EventCancelled" or other values here

Is SHACL able to express all this, and does JSON-LD play along?

   {
     [...]
     "hydra:expects":
     {
       "@type": "sh:Shape",
       "sh:scopeClass": "Event",
       "sh:property": [
         {
           "sh:predicate": "name",
           "sh:minCount": 1,
           "sh:maxCount": 1
         },
         {
           "sh:predicate": "startDate",
           "sh:datatype: "xsd:date"
           "sh:minCount": 1,
           "sh:maxCount": 1,
           "sh:minExclusive": "2015-10-17" <- only future dates
         },
         {
           "sh:predicate": "eventStatus",
           "sh:class": "schema:EventStatusType"
           "sh:minCount": 1,
           "sh:maxCount": 1,
           "sh:in" : {
             "@list": [
               "schema:EventScheduled"
             ]
           }
         }
       ]
     }
   }

While this might seem quite verbose at first, it is not unlike the way HTML5 describes this sort of information to its generic client, the browser. The big difference to a schema is that we are not describing the conditions of a valid instance of an Event, but the conditions for a request that sends a *new* event to the service.