API Discoverability using HYDRA and schema.org

Hello list,

I 'd like to share with you a simple scenario that I've been working on for
a couple of months.

I am trying to automate the process of API discovery using HYDRA +
schema.org.
The API provider describes it's capabilities using terms from those
vocabularies.
The API consumer describes the requested APIs using the same vocabularies
in a simple JSON-LD format.
There is a server between those two named API-Resolver, acting like a
search engine.
The queries and answers are in the form of RDF graphs. Behind the
API-Resolver, lies an instance of Jena/Fuseki as our SPARQL endpoint.
Each API provider is supposed to feed his jsonld complete description to
the API-Resolver in order to be discoverable.
The description of the server contains all the available classes and their
available methods, or better Actions in terms of schema.org.

The process so far is as follows:

1. The client describes the requested APIs with a simple graph
//part of clients description
    },
    "postalAdress": {
      "@type": "PostalAddress",
      "addressCountry": '',
      "addressLocality": ''
    },
    "airport": {
      "@type": "Airport",
      "iataCode": '',
      "address": { "@type": "PostalAddress" },
      "geo": {"@type": "GeoCoordinates"},
      "potentialAction": {
        "@type": "searchAction",
        "object": "schema:Airport",
        "result": "schema:Airport",
        "target": "schema:Airport",
        "query": {"@type": "schema:PostalAddress"}
      }
    },
//
2. Sends the request to API-Resolver who is already known.
3. API-Resolver creates the appropriate SPARQL queries for the triplestore.
//Sample
      DESCRIBE ?class ?target
      WHERE  {
        ?class rdf:type <http://schema.org/Airport>.
        ?server hydra:supportedClass ?class.
        ?server hydra:entrypoint ?entrypoint .
        ?class hydra:supportedProperty ?prop1 .
          ?prop1 hydra:property ?prop1_IRI .
          ?prop1_IRI rdf:type schema:address .
          ?prop1_IRI rdfs:range schema:PostalAddress .
          ?class hydra:supportedProperty ?prop2 .
          ?prop2 hydra:property ?prop2_IRI .
          ?prop2_IRI rdf:type schema:geo .
          ?prop2_IRI rdfs:range schema:GeoCoordinates .
          ?class hydra:supportedProperty ?prop3 .
          ?prop3 hydra:property ?prop3_IRI .
          ?prop3_IRI rdf:type schema:iataCode .
          ?action4_IRI schema:object ?class .
          ?action4_IRI schema:query ?query .
          ?query rdf:type ?queryClass .
          ?queryClass rdf:type schema:PostalAddress .
          ?action4_IRI schema:result ?result .
          ?result rdf:type <http://schema.org/Airport> .
          ?action4_IRI schema:target ?target .
          }
4. The API-Resolver reconstructs those graphs and responds to the client
with a single graph.
5. Client parses this graph and stores it locally using rdflib.js
6. Creates the appropriate classes based on the requested data and binds
the Actions to functions using a utility lib.
7. Inside our main client now, we are using something like this to search
the Airport Collection:

  var schydra = schydraAngular.init(rawJSON,resolverServer,graph);
  schydra.then(function(hydraClass){
    var searchAirport = new hydraClass['Airport'];
    searchAirport.label = 'Search Airport';
    searchAirport.set('iataCode','');
    searchAirport.set('iataCode','IATA code','label');
    searchAirport.set('address',searchAddress);
    searchAirport.set('geo',location);

   searchAddress.set('addressLocality',searchQuery);
   searchAirport.actions.searchAction(graph,'').then(function(response){ ...


The whole chain is already working in this simple manner but I can not
publish it just yet.
I tried to abstract the whole RDF thing from the developer's perspective.
The only thing he needs to know is the vocabulary he is about to use in
order to describe his data model.
What do you think about that?

Keep it up,
Dimitris

Received on Saturday, 27 May 2017 21:17:42 UTC