Schlagwort-Archive: Web of Data

Solid Forms: Deklarative datengetriebene User Interfaces

Kontrolle über die eigenen Daten ist ein wesentliches Ziel von Solid. Dazu werden Daten in User Pods gespeichert und sind unabhängig von bestimmten Apps. Ich kann mir eine passende Anwendung für meine Zwecke aussuchen und diese jederzeit leicht wechseln.

Wirkliche Kontrolle erhält man aber nur, wenn man selbst in der Lage ist Daten zu erzeugen und für sich zu nutzen, ohne abhängig davon zu sein, dass jemand anderes erst eine App entwickelt. Benutzer*innen sollen in der Lage sein, genau die Daten in ihren Pod zu schreiben die sie brauchen. Nicht jede*r kann oder will erst eine komplexe Programmiersprache lernen, um eine App für ein bestimmtes Problem zu entwickeln.

Ein Low Code System für Solid

Das Solid Forms System ermöglicht die deklarative Beschreibung von Eingabeformularen und somit die Erstellung einfacher Anwendungen. Die Formulare werden einfach mittels Linked Data beschrieben (zum Beispiel in Turtle Syntax) und irgendwo im Web hinterlegt (im Pod, auf Github, …). Man kann sie entweder von Hand schreiben, oder eine App nutzen. Solid Forms sind quasi die Low Code / No Code Variante von Solid Apps.

Ein einfaches Solid Form in Turtle Syntax kann wie folgt beschrieben werden:

ex:form a ui:Group
  ui:parts (ex:part1 ex:part2) .

ex:part1 a ui:SingleLineTextField ;
  ui:property vcard:fn;
  ui:label "name" .

ex:part2 a ui:EmailField ;
  ui:property vcard:hasEmail ;
  ui:label "email" .

Dieses Formular besteht aus zwei Eingabefeldern: Eines für den Namen und eines für die E-Mail-Adresse. Diese Form des High-Level-Designs erlaubt mehrere unterschiedliche Implementierungen, also Code der die Formulare dann tatsächlich als User Interface benutzbar macht. Eine solche Implementierung ist Teil von solid-ui, der UI-Bibiothek von SolidOS. Weitere Implementierungen, z. B. in ReactJS und MUI, als Web Components, oder für native Apps sind denkbar.

Rendering des oben beschriebenen Formulars mittels solid-ui

Zur Beschreibung der Eingabefelder benutzt Solid Forms die UI-Ontologie, welche zahlreiche nützliche Felder, von der einfachen Texteingabe bis zum Color-Picker bereits mitbringt. Komplexere Felder können davon abgeleitet werden. Kennt eine Implementierung ein bestimmtes Feld nicht, kann sie auf eine einfachere Eingabevariante zurückfallen, sodass Anwendungen stets benutzbar bleiben.

Solid Forms kennt viele verschiedene Arten von Eingabefeldern (klicken zum Vergrößern)

Wird ein Solid Form abgeschickt, speichert es die Daten im Solid Pod. Jemand der ein Formular erstellen möchte, muss sich also weder um die Programmierung des Frontends, noch des Backends kümmern, sondern kann sich voll und ganz auf die inhaltliche Beschreibung eines Formulars für die benötigten Daten kümmern. Programmierkenntnisse sind dazu nicht erforderlich.

Links die Beschreibung des Formularfeldes, rechts das Rendering durch die Forms-Implementierung (hier solid-ui) und in der Mitte das RDF-Tripel, das im Pod abgespeichert wird. (klicken zum Vergrößern)

Deklarative Micro-Frontends

Ein weiterer interessanter Aspekt ist die mögliche Verlinkung von Formularen. Da es sich um Linked Data handelt, können verschiedene Teile eines Formulars auf unterschiedlichen Servern liegen und von verschiedenen Verantwortlichen gepflegt werden. Man kann also ein ganzes „Web of Forms“ erstellen. Solid Forms ermöglicht damit sozusagen deklarative Micro-Frontends! Natürlich können die Forms auch mit dem Rest des Web of Data verknüpft werden. Autocomplete-Felder können Daten aus öffentlichen Quellen, wie zum Beispiel Wikidata laden, oder Vorschläge aus dem persönlichen Pod einblenden.

Ein durch solid-ui gerendertes Autocomplete mit Vorschlägen aus Wikidata.

Ein Formular für Formulare

Formulare in Turtle zu beschreiben ist zwar einfacher als Programmieren, aber sicher nicht für jede*n etwas. Da Formulare aber auch nur Daten (Linked Data) sind, können sie wie alles andere auch durch Apps erzeugt werden. Dies senkt die Einstiegshürden weiter ab.

Vorsicht, jetzt wird es meta: Eine App zur Erzeugung von Formularen kann auch als Solid Form beschrieben werden. Das „Form Form“ ermöglicht es andere Solid Forms zu erstellen und zu bearbeiten.

Going meta: Mit dem „Form Form“ können Solid Forms mittels UI bearbeitet werden. Dieses UI ist selbst ein Solid Form.

Tim Berners-Lee, der Erfinder des WWW und Begründer von Solid, hat das Forms Systems am Mittwoch persönlich vorgestellt und erklärt. Eine Aufzeichnung seiner Präsentation könnt ihr hier anschauen.

Das Form System ist sehr mächtig, aber noch spärlich dokumentiert. Zukünftig sollen Tutorials für Einsteiger*innen entstehen. Weitere Implementierungen mit einer guten User Experience und Form Registries zur Wiederverwendung von nützlichen Formularen (so etwas wie GitHub für Forms) sind zukünftig denkbar.

Weiterführende Links

Linked-Data-Praxis: Daten bereitstellen und verwerten

In Ausgabe 02/2013 der Zeitschrift java aktuell wurde ein Praxisartikel von mir zum Thema Linked Data veröffentlicht:

Ein Artikel in der letzten Ausgabe hat in die Grundlagen von Linked Data eingeführt und gezeigt, wie daraus ein Web aus Daten entstehen kann. Linked Data ist jedoch keine bloße Theorie: Mit wenigen Zeilen Code kann eine Anwendung Teil dieses Daten-Webs werden. Der Beitrag zeigt, wie man Linked Data veröffentlichen und in seinen Anwendungen verwerten kann.

Im Artikel wird ein Hotel-Service beschrieben, der Hotel-Informationen als Linked Data verfügbar macht. Eine weitere Anwendung konsumiert diese Daten um die Bewertung der Hotels zu ermöglichen. Der beschriebene Hotel-Service ist unter http://hotels.datenwissen.de/ online. Die Hotel-Bewertung ist über http://hotel-rating.datenwissen.de/ möglich. Beide Anwendungen sind Open Source und auf github verfügbar (Hotel-Service, Bewertungsplattform).

Den Artikel könnt ihr hier als PDF herunterladen.

Alle meine Artikel sind ab sofort auch hier verfügbar.

Linked Data in „java aktuell“

In der Ausgabe 01/13 von „Java aktuell“ erschien mein Artikel „Linked Data – ein Web aus Daten“, den ich nun auch an dieser Stelle als PDF bereit stelle. Es handelt sich um eine Einführung in das Thema Linked Data:

Wer heute im Web Daten abrufen möchte, hat es nicht leicht. Obwohl hinter vielen Diensten große Datenbanken stehen, beschränkt sich das Surfen im Web meist noch auf menschenlesbare Webseiten. Entwickler können bestenfalls den mühsamen Umweg über proprietäre APIs gehen. Mit Linked Data werden die Daten Teil des Webs und das dokumentenbasierte World Wide Web erweitert sich um ein Web aus Daten.

In der nächsten Ausgabe erscheint ein Praxisartikel der verdeutlicht, wie leicht man selbst Linked Data bereitstellen und verarbeiten kann. Die Ausgabe erscheint am 06.03.2013.

Linked Data: Mehr als nur RDF

Das Beispiel offenerhaushalt.de zeigt, dass zur Partizipation am Web of Data mehr gehört, als die Veröffentlichung von RDF/XML-Daten. Es lohnt sich dennoch, den Schritt zu „Linked Data“ zu gehen.

Die Veröffentlichung von Daten im RDF-Format gehört zu den Linked Data Grundprinzipien, die Tim Berners-Lee aufgestellt hat. Daher freue ich mich, dass immer mehr Open-Data-Projekte neben JSON und XML, auch Daten in einer RDF-Syntax veröffentlichen.

Das allein reicht aber leider nicht aus, um von Linked Data sprechen zu können, wie ich am Beispiel der RDF/XML-Daten von offenerhaushalt.de zeigen möchte.

Rufen wir uns zunächst die Grundprinzipien noch einmal ins Gedächtnis:

  1. Use URIs as names for things
  2. Use HTTP URIs so that people can look up those names
  3. When someone looks up a URI, provide useful information, using the standards (RDF, SPARQL)
  4. Include links to other URIs. so that they can discover more things

Ich werde diese Prinzipien nun nacheinander mit den RDF-Daten des Haushaltspostens „Bundesministerium für Bildung und Forschung“ von offenerhaushalt.de abgleichen, welche sich im Dokument http://bund.offenerhaushalt.de/30.rdf befinden.

[important]Disclaimer: Auch wenn ich in Sachen Linked Data in diesem Artikel einiges an offenerhaushalt.de zu kritisieren habe, möchte ich dies nicht als generelle Kritik am Projekt verstehen. Im Gegenteil: Ich halte das Projekt für ein Vorzeigebeispiel der Open-Data-Bewegung und spreche allen Beteiligten großen Dank und Respekt aus! Meine Kritik ist im Vergleich zu dem, was bereits geleistet wurde, eine Kleinigkeit. Ich möchte sie eher als Anregung verstanden wissen. Auch bin ich gerne bereit zu helfen, wenn Interesse besteht, die offenen Haushaltsdaten ins Web of Data zu hieven.[/important]

Use URIs as names for things

Wesensmerkmal des Web of Data ist, dass dort nicht nur reine Dokumente („Informationsressourcen„), sondern auch Daten über reale und abstrakte „Dinge“ aufzufinden sind. Diese Dinge benötigen einen global eindeutigen Namen. Genau diese Anforderung erfüllen URIs.

Bei der Namensgebung ist zu beachten, dass das „Ding“ welches beschrieben wird und die Dokumente welche es beschreiben unterschiedlich sind und deshalb auch über unterschiedliche URIs identifiziert werden müssen. Getreu dem Merksatz: „Du bist nicht deine Website„!

Das Datendokument http://bund.offenerhaushalt.de/30.rdf beschreibt ein Subjekt namens http://bund.offenerhaushalt.de/30. Unklar bleibt dabei, um was für eine Art von „Ding“ es sich dabei handelt. Ein rdf:type ist nicht hinterlegt.

Nun liegt die Vermutung nahe, dass bei offenerhaushalt.de Haushaltsposten beschrieben werden. Ruft man jedoch die URI http://bund.offenerhaushalt.de/30 im Browser oder mit Hilfe eines Tools wie curl ab, so wird ein HTML-Dokument zurückgeliefert:

user@pc:~$ curl -I http://bund.offenerhaushalt.de/30
HTTP/1.1 200 OK
Date: Wed, 02 May 2012 18:38:32 GMT
Server: Apache/2.2.14 (Ubuntu)
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 73434
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8

Auch wenn man den Accept-Header explizit auf application/rdf+xml oder text/turtle setzt, wird ausschließlich text/html zurück geliefert.

Bei http://bund.offenerhaushalt.de/30 handelt es sich also schlichtweg um ein herkömmliches HTML-Dokument und nicht um einen Haushaltsposten.

Interessant sind unter diesem Aspekt Aussagen wie zum Beispiel folgende¹:

<http://bund.offenerhaushalt.de/30> openhaushalt:is_department "true".

Das HTML-Dokument ist also eine Abteilung, soso 🙂

Wobei wir streng genommen gar nicht wissen können, was openhaushalt:is_department überhaupt bedeutet. Das Prädikat ist nämlich nicht auflösbar, womit wir beim nächsten Punkt angelangt sind:

Use HTTP URIs so that people can look up those names

Die URI des Prädikats erhält man, indem man das Namespace-Prefix durch die Namespace-URI ersetzt. Für openhaushalt:is_department ergibt sich somit http://offenerhaushalt.de/schema/0.3/is_department. Bei Abruf dieser URI erhält man leider nichts weiter als den HTTP-Fehlercode 404: Not Found. Zwar wurden HTTP-URIs verwendet, diese sind aber nicht abrufbar.

Provide useful information

Bei den abrufbaren URIs scheitert es an „nützlichen Informationen“. Wie schon im ersten Abschnitt bemerkt, liefert http://bund.offenerhaushalt.de/30 lediglich ein HTML-Dokument zurück, wohingegen die RDF-Daten eher auf ein abstraktes „Ding“, wie einen Haushaltsposten oder eine Abteilung, hindeuten.

Dieses „Ding“ müsste zunächst einmal einen eigenen Namen bekommen, z.B. http://bund.offenerhaushalt.de/30#item

Beim Abruf mittels Browser würde durch den Wegfall des Fragment-Identifiers weiterhin das HTML-Dokument http://bund.offenerhaushalt.de/30 ausgeliefert werden, wodurch die „nützlichen Informationen“ zumindest für den menschlichen Klienten weiterhin gewährleistet wären.

Fordert ein Client mittels HTTP-Accept-Header jedoch ausdrücklich RDF, dann muss dieses ebenfalls über die URI http://bund.offenerhaushalt.de/30#item respektive http://bund.offenerhaushalt.de/30 verfügbar sein, da der Client entscheidet, welches Datenformat für ihn nützlich ist. Derzeit wird aber immer HTML ausgeliefert.

Nützlich sind die Daten aber auch deshalb nicht, weil die URIs der Prädikate nicht abrufbar sind. Die verwendete Ontologie ist somit ohne API-Dokumentation nicht zu verstehen. Es bleibt unklar, was Prädikate wie openhaushalt:is_department tatsächlich bedeuten. Die RDF-Daten sind damit kein Zugewinn im Vergleich zu z.B. JSON. Die Semantik fehlt in beiden Varianten.

Include links to other URIs

Die Verlinkung beschränkt sich auf andere URIs innerhalb des Projekts offenerhaushalt.de. Eine Verlinkung ins offene Web of Data findet derzeit nicht statt. Problematisch ist auch hier wieder, dass die URIs lediglich HTML-Dokumente identifizieren und somit auch kein „internes Web of Data“ entsteht. Was bleibt sind RDF/XML-Dokumente mit Links zu HTML-Seiten.

Na und?

Nun stellt sich dem ein oder anderen sicher die Frage, wozu man diese manchmal recht akademisch anmutenden Ansätze überhaupt verfolgen sollte? Die offenen Haushaltsdaten, die derzeit vom Projekt angeboten werden, sind zweifelsohne bereits in der vorliegenden Form sehr wertvoll. Die vorliegenden RDF/XML-Daten bieten aber nach meiner Auffassung keinen Mehrwert gegenüber dem JSON-Format. Im Gegenteil: Sie sind für einen Programmierer eher noch schwerer zu verarbeiten.

In Form von Linked Data können die Daten aber ein Potential entfalten, das deutlich über den Status quo hinaus geht. Eindeutige URIs für Haushaltsposten (nicht die HTML-Seiten!) könnten z.B. auch von anderen Projekten genutzt werden um strukturierte Aussagen über diese Haushaltsposten zu treffen. Denkbar wären zum Beispiel Tools zum Bürgerhaushalt, welche ihre Nutzer die Budgets für die einzelnen Haushaltsposten neu verteilen lassen. Dadurch dass alle über die gleichen (durch URIs global benannten!) Haushaltsposten „sprechen“, ist es dabei völlig egal, auf welchem Server mit welchem Tool solch ein Bürgerhaushalt erstellt wurde. Man kann sich das ähnlich vorstellen wie heute Verlinkungen und Pingbacks in der Blogosphäre, nur dass eben nicht über Dokumente/Blogeinträge „gesprochen“ wird, sondern über Daten und Dinge, wie z.B. Haushaltsposten.

Die Verwendung von einheitlichen Ontologien macht diesen Austausch ebenfalls leichter. Zudem wird eine „API“-Dokumentation letztlich überflüssig, wenn die Prädikate der Ontologien im Web abrufbar sind uns sich auf diese Weise selbst erklären.

Fazit

Das Projekt offenerhaushalt.de stellt RDF/XML-Daten bereit, ist damit aber noch kein Teil des Web of Data. Die folgenden Kritikpunkte zeigten sich bei einem Abgleich mit den Linked Data Prinzipien von Tim Berners-Lee:

  1. URIs identifizieren lediglich Dokumente, aber keine „Dinge“ wie Haushaltsposten.
  2. Die „Ontologie“ besteht nur aus toten Links und ist damit genauso ausdruckslos wie JSON.
  3. Es findet keine Content-Negotiation statt, die Wünsche des Clients werden ignoriert.
  4. Aufgrund von 1. kann es auch keine Links auf „Dinge“ geben. Es entsteht somit kein Web of Data.
  5. Es gibt keine Verlinkungen ins Web of Data.

Werden diese Aspekte angepasst und die Linked Data Prinzipien beachtet, können die Daten von offenerhaushalt.de Teil des Web of Data werden und dadurch ihr volles Potential entfalten.


¹ Zur besseren Lesbarkeit verwende ich hier die TURTLE-Notation, obwohl die Daten im Original als RDF/XML vorliegen. Semantisch macht dies keinen Unterschied. 

Bibliotheksverbund Bayern und KOBV bereichern das Web of Data

Ich bin begeistert! Der Bibliotheksverbund Bayern hat gemeinsam mit dem KOBV (Kooperativer Bibliotheksverbund Berlin-Brandenburg) deren riesige Bestandskataloge als Linked Open Data verfügbar gemacht. Sie bereichern das Web of Data damit um

[…] Beschreibungen zu über 23 Millionen Medien aus 180 wissenschaftlichen Bibliotheken in Bayern, Berlin und Brandenburg. Die Datenbasis umfasst etwa 600 Millionen RDF-Tripel oder 5,5GB als Download

Zunächst dachte ich noch: Schön, aber bestimmt wieder nur ein paar ZIP-Archive zum herunterladen. Es handelt sich jedoch tatsächlich um vollwertige 5-Sterne-Daten! Die Verantwortlichen haben verstanden worum es geht und alles richtig gemacht:

Möglichst viele Links zu anderen Datenbeständen sollen sicherstellen, dass sich die Daten gut in die bestehende LinkedOpenData-Cloud integrieren und keine doppelte Datenpflege stattfindet.

Ein Buch kann sehr eingängig über eine Basis-URI gefolgt von der ISBN-Nummer identifiziert werden:

http://lod.b3kat.de/isbn/<ISBN>

Zum Beispiel identifiziert folgende URI das sehr empfehlenswerte Buch „Clean Code“ von Robert C. Martin:

http://lod.b3kat.de/isbn/0132350882

Da es, wie auch bei diesem Buch, mehrere Ausgaben unter der gleichen ISBN geben kann, werden die unterschiedlichen Ausgaben in folgender Form über einen Katalogschlüssel, die sogenannte BV-Nummer, identifiziert:

http://lod.b3kat.de/title/<BV-Nummer>

Da alle Ausgaben über owl:sameAs von der per ISDN identifizierten Ressource verlinkt sind, ist es jedoch ein leichtes die Ausgaben auch ohne Kenntnis der BV-Nummer aufzuspüren. (Denn was ist einfacher als einem Link zu folgen? 😉 )

Alle Infos zur richtigen Adressierung der Daten sind hier aufgeführt.

[important]Was kann ich nun mit den Daten machen? Verlinken! Wir haben nun für eine gigantische Menge an Büchern und Medien eine URI um sie zu identifizieren. Ich spreche nicht von Links auf eine Amazon-Webseite, es handelt sich um Links auf Bücher! Remember: You are not your Website! Wir können – irgendwo im Web – Rezensionen zu diesen Büchern schreiben und mittels der URIs sagen worauf wir uns beziehen. Wir können in unseren FOAF-Profilen hinterlegen, dass wir diese Bücher mögen, gelesen haben oder besitzen ohne dass wir dazu eine Plattform wie Facebook brauchen. Kurzum: Wir haben die Möglichkeit uns im World Wide Web über diese Bücher auszutauschen und etwas über Sie auszudrücken, ohne dass wir dazu an bestimmte, proprietäre Plattformen und Dienste gebunden sind.[/important]

Darüber hinaus gibt es auch einen SPARQL-Endpoint über den sich die Datenmassen systematisch erschließen lassen. Wer zum Beispiel alle Bücher von  Robert C. Martin ermitteln möchte, kann dies mit folgender Abfrage tun:

PREFIX dc:<http://purl.org/dc/elements/1.1/>
PREFIX dcterms:<http://purl.org/dc/terms/>

SELECT ?uri ?title ?extent WHERE {
  ?uri dc:title ?title;
       dc:creator <http://d-nb.info/gnd/114440964>;
       dcterms:extent ?extent.
}

An diesem Beispiel sieht man auch sehr schön, dass sinnvoll auf andere Datenbestände verlinkt wurde: Die URI http://d-nb.info/gnd/114440964 identifiziert nämlich den Autor Robert C. Martin in den Datenbeständen der Deutschen Nationalbibliothek (Ja, auch die machen erfreulicherweise Linked Data verfügbar!)

Die Bibliotheksverbunde haben hier großartige Arbeit geleistet und bereichern das Web of Data damit sehr!

Picserv: Bilderdienst für das Social Web of Data

Als Teil meines Engagements rund um dezentrale soziale Netzwerke habe ich ein weiteres Projekt gestartet: Einen Bilderdienst à la Twitpic, Arbeitstitel „picserv“.

Zum einen will ich schon lange weg von Twitpic und Co. Solche Dienste sind zwar kostenlos und praktisch, im Kleingedruckten oftmals jedoch nutzerfeindlich. Hinzu kommen die gernerellen Probleme von zentralisierten Diensten, die ich hier beschrieben habe.

Vor einigen Tagen habe ich eine erste Version online genommen, erreichbar unter http://picserv.desone.org. Da meine Serverressourcen begrenzt sind, kann nur ich dort Bilder hochladen. Ihr könnt euch jedoch über Twitter einloggen und Kommentare hinterlassen. Und schließlich ist es ja auch im Sinne der Dezentralisierung, dass sich möglichst viele Menschen eine eigene Instanz von „picserv“ oder ähnlichen Diensten installieren. (Bei Interesse, sagt mir Bescheid)

Als nächstes möchte ich über den Dienst auch Linked Data zur Verfügung stellen, damit die Bilder und Kommentare Teil des Web of Data werden. Auch ein Login über WebID soll möglich werden. Dadurch kann man sein Profil und seine Bilder bei zwei völlig unterschiedlichen Diensten / Servern hosten und trotzdem ist beides im Sinne des „Social Webs“ miteinander verknüpft.

[important]Habt ihr ebenfalls ein interessantes Social-Web-Projekt und möchtet es Teil des Web of Data werden lassen? Ich helfe gerne weiter, wenn ihr noch nicht so richtig wisst wie![/important]

Content-Negotiation mit Grails

Content-Negotiation, zu Deutsch Inhaltsvereinbarung, ermöglicht es dem Webserver unterschiedliche Repräsentationen einer Resource an den Client auszuliefern und ist damit eine wichtige Funktion im Web of Data. Nehmen wir zum Beispiel an, die folgende URI identifiziert die Stadt Berlin:

http://example.com/city/berlin

Web-Browser fordern für gewöhnlich HTML-Dokumente an und sollen daher beim Abruf dieser URI eine schön aufbereitete Webseite mit Informationen über Berlin und ggf. ein paar Bilder ausgeliefert bekommen. Gleichzeitig sollen jedoch auch RDF-Daten über Berlin im Web of Data verfügbar gemacht werden.

In bin ein großer Freund des Grails Web-Frameworks, welches ich sowohl beruflich als auch privat nutze. Mit Grails wird – neben so ziemlich allem was Web-Entwicklung angeht – auch die Content-Negotiation zum Kinderspiel. Ich möchte das an dem bereits angesprochenen Beispiel praktisch verdeutlichen. (Ich gebe allerdings keine Einführung in Grails selbst, dazu verweise ich auf die hervorragende Dokumentation)

Nehmen wir an es gibt eine Domainklasse City, welche in verschiedenen Repräsentationen durch den CityController ausgeliefert werden soll.

Wir legen folgendes Mapping in UrlMappings.groovy an:

static mappings = {
  "/city/$name"(resource: "city")
}

Dadurch werden die Requests an URLs der Form /city/name RESTful gemappt und an den CityController weitergeleitet. D.h. GET-Requests gehen automatisch an die show-Action des Controllers POST an save u.s.w. (Details siehe Grails-Dokumentation). Außerdem wird der Part hinter /city/ als Parameter „name“ in die Action hineingegeben.

Mithilfe des withFormat-Ausdrucks kann der Controller auf verschiedene Anfrageformate unterschiedlich reagieren:

class CityController {
  def rdfRenderer

  def show = {
    def city = City.findByName(params.name)
    withFormat {
      html { return [cityInstance: city] }
      json { render city as JSON }
      rdf { rdfRenderer.render(city) }
    }
  }
}

Der rdfRenderer ist ein fiktives Beispiel. Sowas wird leider nicht von Grails mitgeliefert. RDF lässt sich aber sehr leicht mit groovyrdf generieren. Die Codeblöcke werden bei Anfragen nach den entsprechenden Formaten ausgeführt. html und json liefert Grails von Haus aus mit, was rdf bedeutet muss man jedoch kurz selbst in der Config.groovy bekannt geben:

grails.mime.types = [
  html: ['text/html','application/xhtml+xml'], // bereits vorkonfiguriert
  json: ['application/json','text/json'], // bereits vorkonfiguriert
  // [...]
  rdf: 'application/rdf+xml' // selbst ergänzt
]

Das wars im Prinzip schon, leider gibts in Grails derzeit noch einen kleinen Bug: Grails liest für die Content-Negotiation nicht wie üblich den HTTP-Accept-Header aus, sondern den Content-Type. Der Content-Type gibt eigentlich das Format der Daten an, welche man hinsendet und nicht der Daten welche man anfordert. Das lässt sich aber leicht über eine einfache Konfiguration beheben. Dazu in der Config.groovy folgende Einstellung setzen:

grails.mime.use.accept.header = true

Das wars auch schon! Abhängig vom gesetzten Accept-Header reagiert unser Controller nun anders auf den Request und kann entsprechend eine GSP rendern um eine HTML-Seite auszuliefern, JSON-Daten ausgeben oder aber RDF! Und sogar folgende URIs sind gültig:

http://example.com/city/berlin.html - Liefert immer die HTML-Seite
http://example.com/city/berlin.json - Liefert immer JSON-Daten
http://example.com/city/berlin.rdf - Liefert immer RDF-Daten

Wir haben also mit http://example.com/city/berlin eine eindeutige URI, welche die Resource Berlin identifiziert und zum anfragenden Client passende Daten ausliefert. Zudem haben wir für jede der Repräsentationen eine URI mit der entsprechenden „Dateiendung“. Das ist genau das, was wir im Web of Data brauchen 🙂

RDF – Die Sprache des Web of Data

Nach unserem kurzen Ausflug ins Web of Data, wollen wir nun die Sprache näher betrachten, die diese Daten beschreibt. Was HTML im „normalen“ Web ist, ist hier RDF. RDF beschreibt Ressourcen und steht deshalb – oh Wunder – für Resource Description Framework.

Wir erinnern uns: Im Datenweb gibt es nicht nur Dokumente, sondern alle möglichen Dinge über die wir Daten hinterlegen können, z.B. Städte, Personen, Medikamente, Bücher, Ereignisse, … Diese Dinge nennt man im Datenweb Ressourcen. Die Grammatik von RDF ist einfach: Eine Ressource beschreibt man in der Form Subjekt – Prädikat – Objekt. Dieses Dreigespann heißt RDF-Tripel. Subjekt ist die Ressource, die beschrieben wird, Prädikat ist die Aussage die wir über diese Ressource treffen und Objekt ist der Wert oder Gegenstand dieser Aussage.

Wir können zum Beispiel sagen „Angelo Veltens interessiert sich für Linked Data“ Ich bin in diesem Fall das Subjekt, also die Ressource die wir beschreiben, „interessiert sich“ ist Prädikat und „Linked Data“ das Objekt. Soweit ist es erstmal ein gewöhnlicher deutscher Satz. In RDF-XML sieht der gleiche Sachverhalt folgendermaßen aus:

<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:foaf="http://xmlns.com/foaf/0.1/">

  <foaf:Person rdf:about="http://data.kontroversen.de/foaf.rdf#me">
    <foaf:interest rdf:resource="http://dbpedia.org/resource/Linked_Data"/>
  </foaf:Person>
</rdf:RDF>

http://data.kontroversen.de/foaf.rdf#me ist die URI die mich identifiziert und das Subjekt dieser Aussage. Durch die Verwendung des Tags <foaf:Person> wird zusätzlich noch ausgedrückt, dass die beschriebene Ressource vom Typ foaf:Person ist. Das Tag <foaf:interest> ist ein Prädikat, welches Interesse an einem Themengebiet formal beschreibt. Das Attribut rdf:resource verweist auf das Objekt dieser Aussage. Ich habe hier einen Link in die Dbpedia genutzt um das Themengebiet Linked Data zu identifizieren.

Achtung: RDF ist nicht das selbe wie RDF-XML! XML ist lediglich eine Darstellungsform von RDF. Andere Darstellungsformen sind Notation 3 (N3) oder ein RDF-Graph. In Notation 3 sieht unser Beispiel folgendermaßen aus:

@prefix foaf: <http://xmlns.com/foaf/0.1/>
<http://data.kontroversen.de/foaf.rdf#me>
  foaf:interest
    <http://dbpedia.org/resource/Linked_Data>.

Und hier als RDF-Graph:

simple_rdf_graph

Die eigentliche Herausforderung beim Beschreiben von Ressourcen mittels RDF liegt nicht in der Grammatik, die wie ihr seht wirklich mehr als einfach ist, sondern bei der Wahl und ggf. Neudefinition von Vokabularen, auch Ontologien genannt. Auf einige dieser Ontologien, z.B. das in diesem Beispiel verwendeten FOAF, werde ich in kommenden Artikeln näher eingehen. Zur Definition von Ontologien haben sich zwei Sprachen etabliert: Die Web Ontology Language (kurz OWL) und RDF-Schema. Auch der Eigendefinition von Vokabularen werde ich noch einen Beitrag widmen. Allerdings sollte man damit sehr sparsam umgehen und nach Möglichkeit eine bestehende Ontologie wiederverwerten oder bei Bedarf ergänzen, damit wir ihm Datenweb nicht enden wie beim Turmbau zu Babel und niemand mehr den anderen versteht.

Weiterführende Links:

Data-Browsing – Ein kurzer Ausflug ins Web of Data

Wie versprochen, werden wir das Thema Linked Data nun etwas praktischer angehen. Wenn man mal selbst durch das Datenweb gesurft ist, versteht man viel eher worum es eigentlich geht. Wir brauchen:

  1. Einen Datenbrowser
  2. Einen Einstiegspunkt
  3. Neugier

Es gibt gibt schon einige Datenbrowser, allerdings scheinen die mehr Proof-of-Concept zu sein, als nutzbare Tools. Ich persönlich komme aktuell immer noch am besten mit Tabulator zurecht, obwohl der nicht sonderlich intuitiv zu bedienen ist. Das schöne an Tabulator ist aber, dass es dafür ein Firefox-Addon gibt, das schnell installiert ist. Außerdem lädt Tabulator automatisch „sameAs-Links“ nach, d.h. Daten die unter einer anderen URI verfügbar sind, aber das gleiche Objekt beschreiben werden gleich mitgeladen. Ich werde unsere kleine Erkundungstour durch das Datenweb anhand von Tabulator beschreiben. Wer erstmal nichts installieren mag, kann aber auch einen der Online-Browser verwenden, z.B. den OpenLink Data Explorer, Disco oder Marbles.

Teilweise geht es sogar ganz ohne Datenbrowser, nämlich dann wenn die Datenquellen ihre Daten auch gleich in einer HTML-Variante bereitstellen. Das ist zum Beispiel bei dbpedia.org der Fall. DBpedia ist das Abbild der Wikipedia im Web of Data. Das Projekt liest systematisch Daten aus der Wikipedia aus und veröffentlicht sie als RDF. Unter der URI http://dbpedia.org/resource/Karlsruhe finden sich zum Beispiel Daten zur Stadt Karlsruhe. Ruft man diese URI mit einem normalen Web-Browser ab, werden die Daten als HTML-Dokument angezeigt. Das passiert sogar, wenn man die Tabulator-Erweiterung installiert hat, weil Firefox immer noch primär ein HTML-Browser ist. Wie man das ändern kann erkläre ich in einem späteren Artikel (Tipp für Neugierige: Spielt mal mit Modify Headers am Accept-Header herum). Für den Moment reicht es, explizit die URI http://dbpedia.org/data/Karlsruhe abzurufen, um an die Rohdaten zu kommen [1]. Wir erfahren so tolle Sachen wie die Einwohnerzahl, die Telefonvorwahl und das Bundesland.

Mit Linked Data hat das alles aber noch recht wenig zu tun. Aufgrund der Informationsfülle wird zwar sehr gerne in die DBpedia hinein verlinkt, aber nur sehr wenige Links führen wieder hinaus. Wir suchen uns deshalb einen anderen Startpunkt, am besten von jemandem der sich auskennt: Tim Berners-Lee. Ja, klickt ruhig auf den Link, er führt direkt zu Daten über die Person Tim Berners-Lee, mitsamt einer ganzen Menge Links zu weiterführenden Daten, irgendwo in den Weiten des Webs. Wir erfahren zum Beispiel, dass er der Organisation „World Wide Web Consortium“ angehört und wenn ihr auf den kleinen grauen Pfeil daneben klickt, klappen zusätzliche Infos zu dieser Organisation aus. Wir erfahren auch, dass Berners-Lee der Autor von „Weaving the Web“ ist. Wenn man Shift gedrückt hält, wenn man auf den Pfeil klickt, werden die Daten zu diesem Buch im kompletten Browser-Tab geladen, statt nur ausgeklappt.

Leider stoßen wir dann schon recht schnell an die Grenzen des Datenwebs. Zum Beispiel wird der Verlag des Buches (Harper Paperbacks) zwar genannt, aber nicht verlinkt. Wir können also keine weiteren Daten zum Verlag abrufen. Es liegt an uns allen, diese Grenzen zu sprengen, so wie wir schon das WWW groß gemacht haben und täglich vergrößern. Aber schaut euch einfach mal ein bisschen um, es gibt schon einiges zu entdecken. Unter http://data.kontroversen.de/foaf.rdf#me habe ich auch ein paar Daten über mich online gestellt und mit meinem Identi.ca- sowie Twitter-Account verknüpft. (Ja, dem Thema Datenschutz und informationelle Selbstbestimmung in Bezug zu Linked Data werde ich auch noch einen Beitrag widmen)

So, ich denke das genügt erstmal als kleines, anschauliches Praxisbeispiel bzw. als Startpunkt für eigene Experimente. Bei Fragen und Problemen meldet euch einfach in den Kommentaren.

[1] Genau genommen ist das nicht ganz richtig, denn http://dbpedia.org/data/Karlsruhe verweist auf ein RDF-Dokument mit Daten über die Stadt Karlsruhe, während http://dbpedia.org/resource/Karlsruhe die Stadt selbst identifiziert. Dieser kleine aber feine Unterschied äußert sich auch in der Art wie Tabulator die Daten darstellt.