SpazioCodice

FragLink: un kit di sviluppo per server di frammenti di dati collegati

FragLink: un kit di sviluppo per server Linked Data Fragments

Il Resource Description Framework (RDF) è uno standard del World Wide Web Consortium (W3C).

Originariamente progettato come modello di dati per i metadati, è rapidamente diventato lo standard de facto per descrivere e scambiare dati a grafo, specialmente nelle applicazioni del web semantico.

Fornisce un modo per descrivere risorse e le loro relazioni in un formato leggibile dalle macchine: le informazioni sono strutturate in triplette, dichiarazioni composte da un soggetto, un predicato e un oggetto. Queste triplette formano una struttura a grafo, dove i nodi rappresentano le risorse e gli archi rappresentano le relazioni tra le risorse, come mostrato nell’immagine qui sotto:

Lo stesso grafo può essere rappresentato testualmente utilizzando le dichiarazioni composte:

				
					Andrea knows Mario
Andrea lives in Viterbo
Viterbo is in Italy
Italy is in Europe

Mario lives in Italy
Mario knows John

John lives in Germany
Germany is in Europe
				
			

Come archiviare i dati RDF? L'RDF Store

Un RDF Store, triple store o database RDF, è un database specializzato progettato per archiviare e interrogare dati RDF. Solitamente supporta SPARQL, un linguaggio di interrogazione specifico per i dati RDF.

SPARQL consente agli utenti di esprimere query complesse per recuperare informazioni dall’RDF Store basandosi su schemi e condizioni. Il seguente esempio di query SPARQL recupera i titoli di tutti i libri nel dataset il cui prezzo è inferiore a 30:

				
					PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>
SELECT  ?title ?price
WHERE   { ?x ns:price ?price .
          FILTER (?price < 30) .
          ?x dc:title ?title . }
				
			

Come fornire dati RDF?

Quando ho iniziato a esplorare il tema dei Linked Data Fragments, sono rimasto colpito dalla seguente immagine presente sulla homepage di LDF.

L’immagine offre immediatamente al lettore un’idea chiara di ciò di cui parleremo. I due estremi indicati sono opzioni valide se l’obiettivo è pubblicare e interagire con dati RDF. Esploriamoli brevemente.

Data Dump

Portali RDF come Dbpedia o VIAF offrono accesso online ai loro servizi di ricerca. Tuttavia, essendo servizi pubblici, tale accesso è limitato da una quota d’uso.

Ad esempio, non è possibile creare un sistema che elabori una grande quantità di dati ed esegua rapidamente un numero elevato di chiamate API verso tali servizi. La ragione è chiara: il portale è pensato per offrire servizi di qualità alta/media a un pubblico ampio e potenzialmente vastissimo; di conseguenza, l’impegno marginale in termini di risorse per una singola chiamata API non può superare una determinata soglia.

In questo contesto, cosa puoi fare? Scaricare il dataset pubblico e gestirlo autonomamente in un RDF Store locale, il che ci porta al prossimo estremo.

Server SPARQL

Hai un dataset RDF e vuoi esporre funzionalità SPARQL. Un primo approccio potrebbe essere: “Ok, utilizziamo un RDF Store“.

Fin qui, tutto bene! Tuttavia, l’approccio presenta alcune problematiche, soprattutto se il dataset è considerevole in termini di cardinalità. In questo scenario, il costo elevato del server (il primo dei tre punti elencati come svantaggi dell’estremo SPARQL endpoint) potrebbe giocare un ruolo significativo.

Una soluzione di storage RDF scalabile ha un costo, spesso “importante,” soprattutto se il dataset è ampio; da questa prospettiva, il panorama open-source è piuttosto povero.

Anche optando per una soluzione cloud gestita anziché on-premises, bisogna essere pronti ad aggiungere un nuovo elemento rilevante nella lista della spesa.

Linked Data Fragments

Linked Data Fragments mira a offrire un’alternativa, ossia un terzo scenario intermedio tra i due estremi. L’idea è di destrutturare e distribuire l’esecuzione delle query in piccoli frammenti computazionali.

Invece di avere un motore SPARQL centralizzato (cioè un server), che richiede un costo computazionale elevato, la query SPARQL viene destrutturata in un livello intermedio nei suoi blocchi fondamentali chiamati “triple patterns” (schemi tripli).

Ignoriamo per ora qualsiasi ottimizzazione delle query che il livello intermedio potrebbe applicare (ad esempio, riscrittura delle query o riordinamento degli schemi). Una volta destrutturata la query, ciascun pattern viene inviato a un Triple Pattern Server, un servizio remoto incaricato di “risolvere” un singolo schema triplo.

La risposta della risoluzione dello schema triplo è un frammento, ossia una risposta parziale composta da:

  • Metadati: Informazioni sul risultato, sul dataset, sul servizio e sul sistema sottostante.
  • Controlli ipermediali: Per comprendere e navigare nei risultati.
  • Triplette corrispondenti: Che soddisfano lo schema richiesto.

Il livello intermedio agisce come una sorta di coordinatore di query e motore di federazione: destruttura le query originali, richiede la risoluzione dei pattern risultanti, riceve le risposte dai server di risoluzione dei pattern, applica una logica di fusione e restituisce la risposta al chiamante.

FragLink

FragLink è un framework per costruire server di Frammenti di Dati Collegati. In altre parole, FragLink permette di aggiungere funzionalità di Linked Data Fragments  alla tua applicazione server.

Ciò significa che non è un server autonomo. Si tratta invece di un modulo SpringBoot autoconfigurabile che puoi integrare facilmente nella tua applicazione. Una volta integrato FragLink, tutto ciò che riguarda l’API Web dei Frammenti di Dati Collegati è attivato (cioè il punto di accesso HTTP, i metadati, i controlli): naturalmente, il collegamento concreto dei dati spetta a te.

Vediamo come funziona.

Passo 1: Struttura iniziale di un'app SpringBoot

Questa sarà la tua Linked Data Fragment Server. Si consiglia vivamente di utilizzare Spring Initializr per definire la configurazione iniziale del modulo (ad esempio, componenti, dipendenze, framework, starter).

Passo 2: Dipendenze di FragLink

Una volta creata la struttura iniziale del progetto, apri il file pom.xml (se stai usando Gradle, esiste una configurazione corrispondente) e aggiungi la seguente sezione:

				
					<repositories>
  <repository>
    <id>fraglink-package-registry</id>
    <url>https://gitlab.com/api/v4/projects/52914288/packages/maven</url>
  </repository>
</repositories>
				
			

Il frammento sopra dichiara le coordinate del repository Maven in cui sono ospitati gli artefatti di FragLink. Successivamente, nella sezione delle dipendenze:

Passo 3: Configurazione

Supponendo che tu abbia già configurato tutto nel modulo SpringBoot (ad esempio, le dipendenze, ecc.), ecco la configurazione minima richiesta da FragLink:

				
					<dependency>
  <groupId>com.spaziocodice.labs.rdf</groupId>
  <artifactId>fraglink-starter</artifactId>
  <version>1.1.1</version>
</dependency>
				
			
				
					fraglink:
  base:
    url: https://fragments.yourproject.org  (this is an example)
  page:
    maxStatements: 50 (the maximum number of statements returned in response)
  dataset:
    name: "The dataset / project name" 
    description: "An optional description about the project"
				
			

Passo 4: Avvio

Avvia il tuo server, e dopo qualche secondo dovresti vedere i seguenti messaggi:

				
					... : <FRAGLINK-00001> : FragLink v1.1.1 has been enabled on this server.
				
			

Il server è in esecuzione: fantastico! I Linked Data Fragments sono esposti tramite il root endpoint REST (/). Il template dell’endpoint è:

http://fragments.yourproject.org{subject, predicate, object, graph, page}

Tuttavia, essendo un risolutore di schemi tripli/quadrupli, non sa ancora come recuperare i dati. L’implementazione predefinita è un semplice NoOp, il che significa che non vengono restituiti dati in risposta, ma solo metadati. Ecco un esempio di tale risposta:

				
					<https://fragments.yourproject.org/fragments#metadata> {
    <https://fragments.yourproject.org/fragments#dataset>
            a <http://rdfs.org/ns/void#Dataset> , <http://www.w3.org/ns/hydra/core#Collection>;
            <http://rdfs.org/ns/void#subset>
                    <https://fragments.yourproject.org/fragments>;
            <http://www.w3.org/ns/hydra/core#search>
                    [ <http://www.w3.org/ns/hydra/core#mapping>
                              [ <http://www.w3.org/ns/hydra/core#property>
                                        <http://www.w3.org/1999/02/22-rdf-syntax-ns#subject>;
                                <http://www.w3.org/ns/hydra/core#variable>
                                        "subject"
                              ];
                      <http://www.w3.org/ns/hydra/core#mapping>
                              [ <http://www.w3.org/ns/hydra/core#property>
                                        <http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate>;
                                <http://www.w3.org/ns/hydra/core#variable>
                                        "predicate"
                              ];
                      <http://www.w3.org/ns/hydra/core#mapping>
                              [ <http://www.w3.org/ns/hydra/core#property>
                                        <http://www.w3.org/1999/02/22-rdf-syntax-ns#object>;
                                <http://www.w3.org/ns/hydra/core#variable>
                                        "object"
                              ];
                      <http://www.w3.org/ns/hydra/core#template>
                              "https://fragments.yourproject.org/fragments{?subject,predicate,object,page}";
                      <http://www.w3.org/ns/hydra/core#variableRepresentation>
                              <http://www.w3.org/ns/hydra/core#ExplicitRepresentation>
                    ] .
    
    <https://fragments.yourproject.org#dataset>
            a <http://www.w3.org/ns/hydra/core#Collection>;
            <http://purl.org/dc/elements/1.1/description>
                    "An optional description of the dataset.";
            <http://purl.org/dc/elements/1.1/title>
                    "The Dataset project/name";
            <http://www.w3.org/ns/hydra/core#member>
                    <https://fragments.yourproject.org/fragments#dataset> .
    
    <https://fragments.yourproject.org/fragments#metadata>
            <http://xmlns.com/foaf/0.1/primaryTopic>
                    [ a <https://fragments.yourproject.org/fragments> ] .
    
    <https://fragments.yourproject.org/fragments>
            a <http://www.w3.org/ns/hydra/core#PartialCollectionView>;
            <http://purl.org/dc/elements/1.1/description>
                    "Linked Data Fragment of Share-VDE dataset containing triples matching the pattern {?s ?p ?o ?q}"@en;
            <http://purl.org/dc/elements/1.1/source>
                    "https://fragments.yourproject.org/fragments#dataset";
            <http://purl.org/dc/elements/1.1/title>
                    "Linked Data Fragment of The Share-VDE Project Dataset"@en;
            <http://rdfs.org/ns/void#subset>
                    <https://fragments.yourproject.org/fragments>;
            <http://rdfs.org/ns/void#triples>
                    "0"^^<http://www.w3.org/2001/XMLSchema#long>;
            <http://www.w3.org/ns/hydra/core#firstPage>
                    <https://fragments.yourproject.org/fragments?page=1>;
            <http://www.w3.org/ns/hydra/core#itemsPerPage>
                    "50"^^<http://www.w3.org/2001/XMLSchema#int>;
            <http://www.w3.org/ns/hydra/core#totalItems>
                    "0"^^<http://www.w3.org/2001/XMLSchema#long> .
}
				
			

Passo 5: Risolutore di Frammenti di Dati Collegati

Per creare un collegamento associato a una specifica fonte di dati, devi implementare la seguente interfaccia:

com.spaziocodice.labs.fraglink.service.impl.LinkedDataFragmentResolver

L’interfaccia contiene un unico metodo, che accetta uno schema triplo/quadruplo come input e restituisce una lista di triplette corrispondenti come output. Il framework FragLink utilizza Apache Jena, un potente set di strumenti open-source per gestire i dati RDF.

Anche se implementare un risolutore è semplice, pubblicheremo presto un repository con un esempio pratico di risolutore. Restate sintonizzati!

Link utili

Ci piacerebbe ricevere le vostre domande, dubbi e feedback su questo articolo!
Non esitate a contattarci o a lasciare un messaggio nella sezione commenti qui sotto.

Share this post

Rispondi

Scopri di più da SpazioCodice

Abbonati ora per continuare a leggere e avere accesso all'archivio completo.

Continua a leggere