Il protocollo OData nasce per standardizzare i meccanismi di accesso e di consumo dei dati attraverso l'utilizzo di tecnologie web ampiamente diffuse come l'HTTP ed il protocollo ATOM.
Con delle semplici chiamate HTTP è possibile accedere alle basi dati di un numero sempre più vasto di portali web, come eBay, Flickr, Netflix, Stack Overflow e molti altri.
L'utilizzo di questo protocollo è estremamente semplice, ad esempio navigando all'indirizzo:
otteniamo un XML formattato secondo le specifiche ATOM contenente le informazioni relative agli ultimi 50 post, siano essi domande o risposte, posti sul popolare social network. Chiaramente le interrogazioni possono essere ben più complesse, ad esempio con:
http://data.stackexchange.com/stackoverflow/atom/Posts?$filter=ViewCount%20eq%20100& $orderby=CreationDate%20desc
avremo in risposta solo quei post che hanno ricevuto esattamente 100 visite (ViewCount eq
) ordinate per data di creazione, dalla più recente alla più remota (
100CreationDate desc
).
Concatenando più filtri è possibile rifinire ulteriormente i termini della ricerca proprio come si
farebbe interfacciandosi con una normale sintassi SQL.
OData per FindYourLanguage
Sfruttando il parametro di ricerca inserito dall'utente possiamo attivare una query OData verso Stack Overflow con l'obiettivo di recuperare le 10 domande con il punteggio più alto che trattano del linguaggio oggetto della ricerca.
I dati così recuperati saranno poi visualizzati in una pagina HTML beneficiando di una semplice ma efficace formattazione a griglia. Procediamo per piccoli passi e concentriamoci sull'implementare un processo di interrogazione basato su di una stringa di ricerca fissa, ad esempio 'Javascript'.
Per prima cosa installiamo l'OData Helper beneficiando della procedura attraverso la sezione Amministrazione di ASP.NET Web Pages
che abbiamo sperimentato nella lezione precedente.
Completata l'installazione apriamo nell'editor di WebMatrix il file dettaglio.cshtml
e divertiamoci con qualche sperimentazione, ad esempio provando ad inserire il seguente contenuto:
@{
Layout = "~/shared/layout.cshtml";
var result = OData.Get("http://data.stackexchange.com/stackoverflow/atom/Posts");
var grid = new WebGrid(result);
}
@grid.GetHtml();
e premendo successivamente il pulsante esegui dell'IDE noteremo come queste poche righe di codice siano sufficienti a recuperare le informazioni relative agli ultimi 50 post presenti su Stack Overflow ed impaginarle all'interno di una comoda struttura a griglia.
Ora rifiniamo la query, limitando a 10 il numero dei risultati, ricercando le domande (ignoriamo le risposte), filtrando solamente gli elementi con il termine 'javascript' tra i tag ed introducendo un'ordinamento sull'attributo Score, indicatore del punteggio ottenuto da ogni domanda:
http://data.stackexchange.com/stackoverflow/atom/Posts? $filter=substringof('javascript>',Tags) eq true and PostTypeId eq 1 & $orderby=Score desc & $top=10
Analizziamo nel dettaglio questa interrogazione per scoprire un po' di più sul protocollo OData:
Campo | Descrizione |
---|---|
$filter | questa particella identifica la porzione della query responsabile del filtraggio dei risultati; nell'esempio che stiamo analizzando sono presenti due condizioni concatenate dall'operatore logico and: la prima substringof('javascript>',Tags) eq true identifica tutti gli elementi che contengono nel campo Tags la particella 'javascript' ( il carattere '> ' viene utilizzato da StackOverflow come separatore tra i vari tags ); la seconda, PostTypeId eq 1 richiede che tutti i post recuperati siano domande ( il valore 2 corrisponde a risposte, il 3 ad elementi della wiki) |
$orderby | in questa parte della query specifichiamo il criterio di ordinamento che vogliamo venga applicato al risultato: in questo caso il campo su cui vogliamo insistere è Score ; la particella desc indica che i post dovranno avere un ordinamento decrescente rispetto al campo di cui sopra |
$top | con 10 specifichiamo il numero di elementi che vogliamo la query ci ritorni |
Ci sono altre keyword oltre alle 3 analizzate oggi, così come altre funzioni oltre a substring; per chi voglia approfondire nel dettaglio la parte del protocollo OData relativa alle interrogazioni il consiglio è di leggere la documentazione ufficiale.
Il prossimo passo consiste nell'abbellire e nel rendere fruibile la griglia contenente i dati che abbiamo estrapolato, essendo solo un riassunto potremmo pensare di visualizzare il titolo della domanda, il numero di risposte ed il punteggio (Score) ottenuto. Inoltre sarebbe perfetto far si che attraverso il click sul titolo sia possibile navigare all'URL contenente la domanda in modo da poter visionare anche le eventuali risposte.
Iniziamo con il modificare la pagina default.cshtml
affinando la query OData come abbiamo
appena definito:
var language = "javascript";
var result = OData.Open("http://data.stackexchange.com/stackoverflow/atom/Posts")
.Where("substringof('" + language + ">',Tags) eq true and PostTypeId eq 1")
.OrderBy("Score desc&$top=10")
.Get();
var grid = new WebGrid(result, canSort: false, canPage: false);
Due gli aspetti da notare: in primis la stringa contenente il linguaggio, che nella prossima lezione dovrà essere parametrizzato attraverso il box di ricerca in home, è stata inserita all'interno di una variabile 'language'. Anche la sintassi con la quale viene effettuata la query oData è cambiata, ora è stato introdotto l'uso di alcuni metodi come Where e OrderBy che non modificano nella sostanza il risultato della query ma rendono il codice dell'invocazione più leggibile (più informazioni su questa sintassi sono disponibili sulla documentazione ufficiale dell'Helper).
Inoltre, avendo già impostato sia ordinamento che numero di record richiesti all'interno dell'interrogazione verso StackOverflow, è una buona idea rimuovere queste features dalla WebGrid, operazione facilmente eseguibile attraverso l'impostazione dei due parametri canSort e canPage a false.
Ora completiamo la pagina:
<section id="risposta">
<h1>Tutto e ancora di più in merito a @language</h1>
@grid.GetHtml(
tableStyle: "domande",
headerStyle: "domande_header",
columns: grid.Columns(
grid.Column("Title", header: "Titolo",
format:@<a href="http://stackoverflow.com/questions/@item.Id" target="_blank">@item.Title</a>),
grid.Column("Score", header: "Punteggio"),
grid.Column("AnswerCount", header: "Risposte")
)
)
<footer>
<a href="/">« ritorna al box di ricerca</a>
</footer>
</section>
Il metodo GetHtml
si è arricchito di alcuni parametri interessanti, i primi due servono per valorizzare a nostro piacimento l'attributo HTML class di alcuni elementi (rispettivamente la tabella e l'elemento contenitore delle intestazioni) in modo da rendere più agevole la formattazione CSS. Il terzo parametro contiene invece una collezione di colonne che indicano al componente WebGrid
quali proprietà dei record ottenuti tramite oData debbano essere stampate a video ed in che ordine.
Notiamo poi come per la colonna responsabile della stampa di Title
sia stato specificato, attraverso la keyword format
, uno snippet HTML capace di rendere il titolo della domanda un link verso la domanda stessa direttamente su StackOverflow.
Ora un pizzico di CSS, aggiungiamo in coda al file frontend.css
quanto segue:
/* la tabella delle risposte */
section#risposta .domande {
margin: 20px auto;
}
/* ogni cella della tabella */
section#risposta .domande td {
padding: 1px 3px;
}
/* le intestazioni delle colonne */
section#risposta .domande_header th {
text-align: center;
font-weight: bold;
background: #eee;
padding: 0px 4px;
}
Eseguiamo il progetto nel browser e navighiamo sulla pagina default.cshtml
per verificare quanto costruito: