SpazioCodice

INTERROGAZIONE DI DATI RDF SENZA INTERRUZIONI

Interrogazione di Dati RDF Senza Interruzioni: Server di Frammenti di Dati Collegati guidati da FragLink

Nell’articolo precedente, abbiamo illustrato FragLink, un framework per abilitare le capacità di Frammenti di Dati Collegati alla tua applicazione server.

Come detto in precedenza, FragLink non è di per sé un server. Invece, si presenta come un modulo di autoconfigurazione che puoi facilmente integrare nella tua applicazione.

Una volta configurato FragLink, tutto ciò che è relativo all’API Web dei Frammenti di Dati Collegati è abilitato (ad esempio, endpoint HTTP, metadati, controlli): naturalmente, il legame con i dati concreti dipende da te.

Questo articolo è una guida passo dopo passo che illustra come utilizzare FragLink per implementare un Server di Frammenti di Dati Collegati, specificamente un Server di Triple Pattern.

Il Modello di Dominio (esempio)

Abbiamo un progetto che memorizza i suoi dati in un database relazionale. Il progetto gestisce informazioni personali sui contatti dei nostri clienti; il modello di dominio è semplice (l’abbiamo semplificato per questo articolo).

Abbiamo un elenco di aziende; per ciascuna, memorizziamo i contatti corrispondenti e i loro ruoli (ad esempio, rappresentante dei clienti, CEO, fornitore).

Fortunatamente, la nostra azienda è piccola, quindi l’intero dataset è ridotto. Ecco i contatti al momento della scrittura:

XYZ Ltd

VAT: 00238238123

  • Mr. Ken Smith, CEO, k.smith@xyz.org, +39200232383, +992392929 
  • Mrs. Dora Hug, Sales Director, d.hug@xyz.org, +39232888318, +999230132 
  • Mrs. Lyu Key, Customer Service, l.key@xyz.org, +39200245351, +9900203823 

ABC SRL

VAT: 01648827372

  • Mrs. Lia Dotti, CEO, lia.dotti@abc.it, +393628294745, +3908882382 
  • Mr. Giovanni Rossi, CTO, giovanni.rossi@abc.it, +3987663552, +39088882992  
  • Mr. Ugo Bianchi, Sales, ugo.bianchi@abc.it, +393857733645, +39088882765

JYY SRL

VAT: 02627717271

  • Mr. John Doe, CEO, john.doe@jyy.com, +2382917337, +9832723728 
  • Mr. Johnatan Hellis, Sales, johnatan.hellis@jyy.com, +9283829838, +29382938  

Come rappresentare tale dataset?

Sebbene ci siano diverse scelte riguardo le ontologie per rappresentare un dataset (piccolo) come questo, manteniamo le cose semplici: useremo FOAF e DC. Ecco il nostro dataset in RDF:

				
					<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
    xmlns:org="http://www.w3.org/ns/org#">
  
  <foaf:Person rdf:about="https://spaziocodice.com/people/KenSmith">
    <foaf:name>Ken Smith</foaf:name>
    <foaf:title>CEO</foaf:title>
    <foaf:mbox rdf:resource="mailto:k.smith@xyz.org"/>
    <foaf:phone>+39200232383</foaf:phone>/>
    <foaf:phone>+992392929</foaf:phone>
    <org:role>CEO</org:role>
  </foaf:Person>

  <foaf:Person rdf:about="https://spaziocodice.com/people/DoraHug">
    <foaf:name>Dora Hug</foaf:name>
    <foaf:title>Sales Director</foaf:title>
    <foaf:mbox rdf:resource="mailto:d.hug@xyz.org"/>
    <foaf:phone>+39232888318</foaf:phone>
    <foaf:phone>+999230132</foaf:phone>
    <org:role>Sales Director</org:role>
  </foaf:Person>

  <foaf:Person rdf:about="https://spaziocodice.com/people/LyuKey">
    <foaf:name>Lyu Key</foaf:name>
    <foaf:title>Customer Service</foaf:title>
    <foaf:mbox rdf:resource="mailto:l.key@xyz.org"/>
    <foaf:phone>+39200245351</foaf:phone>
    <foaf:phone>+9900203823</foaf:phone>
    <org:role>Customer Service</org:role>
  </foaf:Person>

  <foaf:Person rdf:about="https://spaziocodice.com/people/LiaDotti">
    <foaf:name>Lia Dotti</foaf:name>
    <foaf:title>CEO</foaf:title>
    <foaf:mbox rdf:resource="mailto:lia.dotti@abc.it"/>
    <foaf:phone>+393628294745</foaf:phone>
    <foaf:phone>+3908882382</foaf:phone>
    <org:role>CEO</org:role>
  </foaf:Person>

  <foaf:Person rdf:about="https://spaziocodice.com/people/GiovanniRossi">
    <foaf:name>Giovanni Rossi</foaf:name>
    <foaf:birthday>1977-03-10</foaf:birthday>
    <foaf:title>CTO</foaf:title>
    <foaf:mbox rdf:resource="mailto:giovanni.rossi@abc.it"/>
    <foaf:phone>+3987663552</foaf:phone>
    <foaf:phone>+39088882992</foaf:phone>
    <org:role>CTO</org:role>
  </foaf:Person>

  ...
  
  <foaf:Organization rdf:about="https://spaziocodice.com/organizations/XYZLtd">
    <foaf:name>XYZ Ltd</foaf:name>
    <foaf:vat>00238238123</foaf:vat>
    <foaf:member rdf:resource="https://spaziocodice.com/people/KenSmith"/>
    <foaf:member rdf:resource="https://spaziocodice.com/people/DoraHug"/>
    <foaf:member rdf:resource="https://spaziocodice.com/people/LyuKey"/>
  </foaf:Organization>

  <foaf:Organization rdf:about="https://spaziocodice.com/organizations/ABCSRL">
    <foaf:name>ABC SRL</foaf:name>
    <foaf:vat>01648827372</foaf:vat>
    <foaf:member rdf:resource="https://spaziocodice.com/people/LiaDotti"/>
    <foaf:member rdf:resource="https://spaziocodice.com/people/GiovanniRossi"/>
    <foaf:member rdf:resource="https://spaziocodice.com/people/UgoBianchi"/>
  </foaf:Organization>

  <foaf:Organization rdf:about="https://spaziocodice.com/organizations/JYYSRL">
    <foaf:name>JYY SRL</foaf:name>
    <foaf:vat>02627717271</foaf:vat>
    <foaf:member rdf:resource="https://spaziocodice.com/people/JohnDoe"/>
    <foaf:member rdf:resource="https://spaziocodice.com/people/JohnatanHellis"/>
  </foaf:Organization>
</rdf:RDF>
				
			

Finora tutto bene. Ora abbiamo bisogno di un endpoint SPARQL affinché clienti, applicazioni e altre entità possano consumare i nostri dati.

API per Dati Collegati: Architettura

Ecco un diagramma dall’articolo precedente:

Ci affideremo al progetto open-source Comunica come Client per Frammenti di Dati Collegati. In quel contesto, è incaricato di:

  • esporre l’endpoint SPARQL
  • ricevere le query dei client
  • eseguire le query distribuendo i modelli di tripla composti attraverso i server di Frammenti di Dati Collegati disponibili
  •  

Il nostro ruolo è implementare il Server di Frammenti di Dati Collegati usando FragLink, un framework open-source.

L’articolo su Fraglink e nel   FragLink repository descrivono i passaggi necessari per creare uno scheletro di progetto. Questo post parte da lì, specificamente implementando il Triple Pattern Resolver. 

Il Resolver di Frammenti di Dati Collegati

Per creare un legame legato a una specifica fonte di dati, devi creare un’implementazione di:

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

L’interfaccia contiene un unico metodo, che prende come input un modello di tripla/quadrupla e si aspetta una lista di triple corrispondenti come output. Il framework FragLink utilizza Apache Jena,

un potente insieme di strumenti open-source per gestire i dati RDF.

Quindi, il nostro compito è “semplice”: dobbiamo fornire l’implementazione di quell’interfaccia, e specificamente per il metodo:

				
					TriplePatternResponse linkedDataFragment(
                            Optional<String> subject, 
                            Optional<String> predicate, 
                            Optional<String> object, 
                            Optional<String> graph, 
                            Optional<Integer> pageNumber, 
                            HttpServletRequest request)
				
			

Il Client di Dati Collegati invierà una o più richieste di modelli di tripla attraverso quell’interfaccia; l’implementazione dovrebbe tradurre queste richieste nelle triple corrispondenti (incapsulate nell’istanza di TriplePatternResponse).

Per esempio, una richiesta come questa:

				
					?s foaf:name ?o
				
			

Dovrebbe rispondere con tutte le triple che hanno <foaf:name> come predicato, indipendentemente dal soggetto o dall’oggetto. Nel nostro dataset, dovrebbe essere qualcosa del genere:

				
					<http://acme.com/people/KenSmith> <foaf:name> "Ken Smith" .
<http://acme.com/people/DoraHug> <foaf:name> "Dora Hug" .
<http://acme.com/people/LyuKey> <foaf:name> "Lyu Key" .
...


				
			

Parole al vento, mostrami il codice!

Il repository di esempio contiene un server di frammenti di dati collegati costruito su FragLink. Da notare che questo esempio è stato costruito in un giorno; lo scopo è illustrare la potenza di produrre dati RDF in tempo reale senza avere un archivio RDF dedicato.

Il repository è un modulo Springboot semplice che implementa lo scenario Contatto-Azienda descritto sopra.

I dati sono memorizzati in un database relazionale “in memoria” H2 (vedi il file resources/data.sql), che ti permette di avviare la demo senza preoccuparti di database e archiviazione.

Due oggetti di accesso ai dati sono incaricati di estrarre e tradurre il risultato delle esecuzioni delle query.

Ecco fatto: a parte la logica di estrazione e traduzione, tutto il resto (ad esempio, metadati, controlli) è gestito da FragLink.   

Se vuoi eseguire l’esempio, ecco cosa ti serve:  

  •  Java 17 o superiore
  • Apache Maven 3.x
  • Git

Passo #1: Clona il repository, costruisci il progetto

				
					> git@github.com:spaziocodice/linked-data-fragment-server-example.git

> cd linked-data-fragment-server-example.git

> mvn clean install
				
			

Dovresti vedere i seguenti messaggi:

				
					...
[INFO] Installing  ... simple-ldf-server-1.0-SNAPSHOT.pom
[INFO] Installing  ... simple-ldf-server-1.0-SNAPSHOT.jar
[INFO] --------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] --------------------------------------------------
[INFO] Total time:  1.429 s
[INFO] Finished at: 2024-04-24T20:14:09+02:00
[INFO] --------------------------------------------------
				
			

Passo #2: Avvia il Server di Frammenti di Dati Collegati

				
					> cd target

> java -jar simple-ldf-server-1.0-SNAPSHOT.jar
				
			

Dovresti vedere i seguenti messaggi:

				
					...
2024-04-24 ... <FRAGLINK-00001> : FragLink v2.0.0 has been enabled on this server.
2024-04-24 ... Started App in 2.706 seconds 
				
			

Passo #3: Sperimenta usando alcune query SPARQL

Useremo comunica.dev come Client di Frammenti di Dati Collegati. Apri il tuo browser preferito e vai su https://query.comunica.dev/.

L’interfaccia utente ti permette di scegliere un dataset da un elenco predefinito. Puoi anche digitare manualmente l’URL di un endpoint SPARQL. Assicurati di inserire in quel campo di testo: https://127.0.0.1:8080/fragments (l’endpoint del server che hai appena avviato nel passo precedente).

Sei pronto. Per iniziare, digita una query valida nell’area di testo sotto. Ecco alcuni esempi di query.

Esempio #1: Dammi tutto!
				
					SELECT ?s ?p ?o
WHERE 
{
  ?s  ?p ?o  . 
}
				
			
Esempio #2: Dammi tutto riguardo a un cliente
				
					PREFIX customers: <https://spaziocodice.com/customers/>

SELECT ?p ?o
WHERE 
{
  customers:1  ?p ?o  . 
}
				
			
Esempio #3: Dammi i clienti (URI) e il loro ruolo
				
					PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX org: <http://www.w3.org/ns/org#>

SELECT ?s ?email ?role
WHERE 
{
  ?s 	foaf:mbox 	?email	. 
  ?s 	org:role 	?role 	.
}
				
			
Esempio #4: Dammi i clienti (URI) e il nome della loro azienda
				
					PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?s ?companyName
WHERE 
{
  ?s	foaf:member ?o  . 
  ?o	foaf:name ?companyName .	
}
				
			

Ricorda: il repository è un semplice esempio; sono sicuro che contenga molte ridondanze e, se inizi a sperimentare con altre query, molti problemi, anche.

Concentriamoci sul concetto di base: abbiamo un database relazionale semplice e, dopo aver implementato un’interfaccia diretta (il contratto del server di pattern di tripla), abbiamo fornito i nostri dati in RDF.

Questo apre molte possibilità, inclusi i mapping dinamici o l’utilizzo di altri tipi di archiviazione (ad esempio, NoSQL).

Divertiti!     

Ci piacerebbe ricevere domande, dubbi e feedback su questo post del blog! Non esitare a contattarci o a lasciare un messaggio nel box dei 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