Linked Data & Hypermedia-Driven Web APIs

Thomas Bergwinkl @bergi_bergos


Chief Research Officer, Zazuko

Software Engineer, bulwiengesa

Agenda

  • Linked Data (Konzept, Standards, JavaScript)
  • Hypermedia-Driven Web APIs (Idee, Hydra)
  • Linked Data Hypermedia-Driven Web APIs für Home Automation

Linked Data

RDF Konzept

Im Anfang war das Wort die Tabelle

User

IDName
1Thomas Bergwinkl
2Melvin Carvalho
3Andrei Sambra
4Nicola Greco

Knows

SourceTarget
12
13
14

Dann kam die IRI

User

IDName
https://www.bergnet.org/people/bergi/card#meThomas Bergwinkl
http://melvincarvalho.com/#meMelvin Carvalho
https://deiu.rww.io/profile/card#meAndrei Sambra
https://nicola.databox.me/profile/card#meNicola Greco

Knows

SourceTarget
https://www.bergnet.org/people/bergi/card#mehttp://melvincarvalho.com/#me
https://www.bergnet.org/people/bergi/card#mehttps://deiu.rww.io/profile/card#me
https://www.bergnet.org/people/bergi/card#mehttps://nicola.databox.me/profile/card#me

Dann das Predicate

IDhttp://schema.org/name
https://www.bergnet.org/people/bergi/card#meThomas Bergwinkl
http://melvincarvalho.com/#meMelvin Carvalho
https://deiu.rww.io/profile/card#meAndrei Sambra
https://nicola.databox.me/profile/card#meNicola Greco
Sourcehttp://schema.org/knows
https://www.bergnet.org/people/bergi/card#mehttp://melvincarvalho.com/#me
https://www.bergnet.org/people/bergi/card#mehttps://deiu.rww.io/profile/card#me
https://www.bergnet.org/people/bergi/card#mehttps://nicola.databox.me/profile/card#me

Dann die Triples

Triples

SubjectPredicateObject
https://www.bergnet.org/people/bergi/card#mehttp://schema.org/nameThomas Bergwinkl
http://melvincarvalho.com/#mehttp://schema.org/nameMelvin Carvalho
https://deiu.rww.io/profile/card#mehttp://schema.org/nameAndrei Sambra
https://nicola.databox.me/profile/card#mehttp://schema.org/nameNicola Greco
https://www.bergnet.org/people/bergi/card#mehttp://schema.org/knowshttp://melvincarvalho.com/#me
https://www.bergnet.org/people/bergi/card#mehttp://schema.org/knowshttps://deiu.rww.io/profile/card#me
https://www.bergnet.org/people/bergi/card#mehttp://schema.org/knowshttps://nicola.databox.me/profile/card#me

Specification

RDF 1.1 Concepts and Abstract Syntax

Formate

N-Triples

<https://www.bergnet.org/people/bergi/card#me> <http://schema.org/name> "Thomas Bergwinkl" .
<https://www.bergnet.org/people/bergi/card#me> <http://schema.org/knows> <http://melvincarvalho.com/#me> .
<https://www.bergnet.org/people/bergi/card#me> <http://schema.org/knows> <https://deiu.rww.io/profile/card#me> .
<https://www.bergnet.org/people/bergi/card#me> <http://schema.org/knows> <https://nicola.databox.me/profile/card#me> .
<http://melvincarvalho.com/#me> <http://schema.org/name> "Melvin Carvalho" .
<https://deiu.rww.io/profile/card#me> <http://schema.org/name> "Andrei Sambra" .
<https://nicola.databox.me/profile/card#me> <http://schema.org/name> "Nicola Greco" .

Turtle

@prefix s: <http://schema.org/> .

<https://www.bergnet.org/people/bergi/card#me>
  <s:name> "Thomas Bergwinkl" ;
  <s:knows>
    <http://melvincarvalho.com/#me>,
    <https://deiu.rww.io/profile/card#me>,
    <https://nicola.databox.me/profile/card#me> .

<http://melvincarvalho.com/#me>
  <s:name> "Melvin Carvalho" .

<https://deiu.rww.io/profile/card#me>
  <s:name> "Andrei Sambra" .

<https://nicola.databox.me/profile/card#me>
  <s:name> "Nicola Greco" .

JSON-LD

{
  "@context": {
    "@vocab": "http://schema.org/",
    "knows": {
      "@type": "@id"
    }
  },
  "@graph": [{
    "@id": "https://nicola.databox.me/profile/card#me",
    "name": "Nicola Greco"
  }, {
    "@id": "http://melvincarvalho.com/#me",
    "name": "Melvin Carvalho"
  }, {
    "@id": "https://deiu.rww.io/profile/card#me",
    "name": "Andrei Sambra"
  }, {
    "@id": "https://www.bergnet.org/people/bergi/card#me",
    "knows": [
      "http://melvincarvalho.com/#me",
      "https://deiu.rww.io/profile/card#me",
      "https://nicola.databox.me/profile/card#me"
    ],
    "name": "Thomas Bergwinkl"
  }]}

weitere Standards

Verbreitung

RDF & JavaScript (RDF-Ext)

JavaScript Bibliotheken

  • JSON-LD
  • N3.js
  • rdflib.js
  • RDF-Ext

RDF-Ext - Parser und Serializer

  • Unterstützung für die verbreitetsten Formate (Turtle, JSON-LD, XML)
  • Callback, Promise und Streaming Interface

RDF-Ext - Clownface für Graph Traversierung

var cf = rdf.cf.Graph(graph);

// start at Amy Farrah Fowlers IRI node
var result = cf.node('http://localhost:8080/data/person/amy-farrah-fowler')
    // search all people Amys knows using the predicate schema.org/knows in subject -> object direction
    .out('http://schema.org/knows')
    // search all given names of known people using the predicate schema.org/givenName in subject -> object direction
    .out('http://schema.org/givenName')
    // return the array of given names of all known people as an array of string values
    .literal()
    // and join the values separated by commas for output
    .join(',');
Quelle: RDF-Ext Primer

RDF-Ext - SimpleRDF Graph to Object Mapping

var blogContext = {
    name: 'http://schema.org/name',
    post: {
        '@id': 'http://schema.org/post',
        '@array': true
    },
    headline: 'http://schema.org/headline',
    content: 'http://schema.org/content'
}

var blog = simple(blogContext, 'http://example.org/blog')

var blogPostA = blog.child()
blogPostA.headline = 'first post'
blogPostA.content = 'this is my first blog post'
blog.post.push(blogPostA)

var blogPostB = blog.child()
blogPostB.headline = 'second post'
blogPostB.content = 'this is my second blog post'
blog.post.push(blogPostB)
<http://example.org/blog> <http://schema.org/post> _:b1 , _:b2 .

_:b1
    <http://schema.org/headline> "first post" ;
    <http://schema.org/content> "this is my first blog post" .

_:b2
    <http://schema.org/headline> "second post" ;
    <http://schema.org/content> "this is my second blog post" .
Quelle: SimpleRDF

Hypermedia-Driven Web APIs

Idee

HTML Interfaces enthalten Elemente für die Navigation

APIs sollten sich ebenfalls selbst beschreiben

Die Beschreibung sollte maschinenlesbar sein

und dezentralle Strukturen erlauben

Links in APIs

Hypermedia as the Engine of Application State (HATEOAS) ist ein Entwurfsprinzip von REST-Architekturen. Bei HATEOAS navigiert der Client einer REST-Schnittstelle ausschließlich über URLs, welche vom Server bereitgestellt werden.

Quelle: Wikipedia

Hydra

Hydra kombiniert HATEOAS und RDF/Linked Data.

W3C Community Group

Header

Link: <$apiUrl>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"

Strukturen

{
    "@context": {"@vocab": "http://www.w3.org/ns/hydra/core#"},
    "@id": "/hydra/api-demo/vocab",
    "@type": "ApiDocumentation",
    "supportedClass": [{
        "@id": "http://www.markus-lanthaler.com/hydra/api-demo/vocab#User",
        "@type": "Class",
        "http://www.w3.org/2000/01/rdf-schema#label": "User",
        "supportedOperation": [{
            "@type": "Operation",
            "http://www.w3.org/2000/01/rdf-schema#label": "Deletes a User entity",
            "method": "DELETE",
            "returns": {"@id": "http://www.w3.org/2002/07/owl#Nothing"},
            "statusCodes": []
        }],
        "supportedProperty": [{
            "title": "raised_issues",
            "property": {
                "@id": "http://www.markus-lanthaler.com/hydra/api-demo/vocab#User/raisedIssues",
                "@type": "Link",
                "http://www.w3.org/2000/01/rdf-schema#domain": {"@id": "http://www.markus-lanthaler.com/hydra/api-demo/vocab#User"},
                "http://www.w3.org/2000/01/rdf-schema#label": "raised_issues",
                "http://www.w3.org/2000/01/rdf-schema#range": {"@id": "http://www.w3.org/ns/hydra/core#Collection"},
                "supportedOperation": {
                    "@type": "Operation",
                    "http://www.w3.org/2000/01/rdf-schema#label": "Retrieves the issues raised by a User entity",
                    "method": "GET",
                    "returns": {"@id": "http://www.w3.org/ns/hydra/core#Collection"},
                    "statusCodes": {
                        "statusCode": 404
                    }
                }
            },
            "readonly": true,
            "writeonly": false
        }]
    }]
}
Hydra Console
Quelle: Hydra API-Demo

JavaScript

hydra.model.load(baseUrl, context).then(function (entryPoint) {
    var user = entryPoint.api.findClass('http://www.markus-lanthaler.com/hydra/api-demo/vocab#User').create()

    user.name = 'bergi'
    user.email = 'bergi@example.org'
    user.password = '123456'

    return entryPoint.registerUser.post(user)
}).then(function (registeredUser) {

})

Linked Data Hypermedia-Driven Web APIs für Home Automation

Weshalb?

  • IRIs erlauben beliebige Strukturen
  • auch bei Operationen
  • man "spricht" nur HTTP

Hydra-Middleware

  • Operationen werden auf Basis von SimpleRDF Objekten implementiert
  • Factory mit Routing erlaubt IRI Strukturen ähnlich denen von Express
  • als Express Middleware implementiert

Web Components

<dh-state-toggle-button iri="http://example.org/living-room/light"></dh-state-toggle-button>

Es muss nur die Geräte IRI angegeben werden, mit Hydra werden die API Informationen nachgeladen.

Intelligente Steuerung mit neuronalen Netzen

Verkettung von Operationen

Mehere Operationen können in einer Promise-Chain verkettet werden um numerischer Werte zu erzeugen. Hydra Operationen liefern auch Informationen über die Ein- und Ausgangsdaten. Ein Wizard könnte zur Erstellung der Verkettung genutzt werden.

// Temperaturen von -50 bis +50 Grad auf 0-1 skalieren
return thermometer.getTemperature().then(add(50)).then(scale(100))

// Zuhause?
return calendar.getCurrentEvent().then(getEventLocation).then(getDistance('48° 32′ N, 12° 9′ O'))

Noch Fragen?