Nel corso della guida esploreremo le funzionalità di ASP.NET Web API creando una semplice applicazione REST che ci consentirà di gestire un glossario online, un elenco di definizioni richiamabili dall'utente specificando un termine. Un client che accede al glossario mediante le API che andremo a creare potrà richiedere la definizione di un termine, l'elenco delle definizioni di una determinata categoria e, se autorizzato, potrà aggiungere, modificare o eliminare le voci del glossario.
Dopo avere scaricato ed installato tutto l'occorrente, lanciamo Visual Web Developer o Visual Studio e creiamo un nuovo progetto basato sul template ASP.NET MVC 4 Web Application.
Nella successiva finestra di dialogo selezionamo Web API come tipo di progetto.
Verrà generato tutto il necessario per poter partire con la realizzazione di un'applicazione MVC 4 che definisce un insieme di API RESTful.
Prima di partire con l'implementazione vera e propria, occorre aver chiaro come è strutturata una Web API e come funziona internamente il sistema. Una Web API è costituita essenzialmente da risorse accessibili via Web tramite una o più rappresentazioni.
Una risorsa è generalmente un'istanza di una classe che viene inviata al client dopo averla serializzata. ASP.NET Web API supporta in maniera predefinita la serializzazione in JSON e XML. Ciascuna risorsa è rintracciabile sul Web tramite uno specifico URI, mappato nel nostro framework sfruttando il meccanismo di routing di ASP.NET. La gestione dei metodi HTTP applicabili alle risorse è affidata ai Controller, un tipo di classe i cui metodi implementano le richieste giunte all'applicazione via HTTP.
In sostanza, un client richiede l'esecuzione di un metodo HTTP, ad esempio GET, su una risorsa identificata da un URI. Il framework, interpretando l'URI, individua il controller associato alla risorsa e, in base allo specifico metodo HTTP ed ai parametri specificati dal client, invoca il metodo corrispondente. Il risultato dell'esecuzione del metodo è una risorsa e/o un codice di stato HTTP. Se viene restituita una risorsa, questa viene serializzata in base al formato richiesto dal client tramite l'intestazione HTTP Accept.
Alla luce di quanto abbiamo descritto, vediamo come implementare la nostra prima API che consente di ottenere la definizione di un termine.
Creiamo innanzitutto una cartella Resources
all'interno del progetto e definiamo in essa una classe Item. Questa classe rappresenterà una voce del glossario, intesa come l'insieme di un termine e della sua definizione, come specificato dal seguente codice.
public class Item
{
public string term { get; set; }
public string definition { get; set; }
}
La creazione della cartella Resources non sarebbe tecnicamente obbligatoria, ma è opportuno crearla per una migliore organizzazione degli elementi del progetto.
Una volta definita la nostra risorsa, creiamo un controller per gestire le relative richieste HTTP inviate dal client. Nella cartella Controllers del nostro progetto aggiungiamo un API Controller vuoto e lo chiamiamo ItemsController
.
Verrà creata una classe derivata da ApiController che andremo a completare con il seguente codice:
public class ItemsController : ApiController
{
List items = new List
{
new Item { term = "API", definition = "Insieme di subroutine o di funzioni che un programma..."},
new Item { term = "World Wide Web", definition = "L'insieme delle informazioni pubblicate..."},
new Item { term = "HTTP", definition = "Protocollo per il trasferimento di..."}
};
public Item GetItemByTerm(string id)
{
var myVoce = items.FirstOrDefault((p) => p.term == id);
if (myVoce == null)
{
var resp = new HttpResponseMessage(HttpStatusCode.NotFound);
throw new HttpResponseException(resp);
}
return myVoce;
}
}
Per semplicità, vista la natura didattica della guida, abbiamo mantenuto le voci del glossario in una lista. Nella realtà le voci andrebbero memorizzate in un database e gestite tramite apposite query.
L'unico metodo al momento disponibile è GetItemByTerm()
che prevede un parametro id
, rappresentante il termine da ricercare, e restituisce la specifica istanza della classe Item se esiste, altrimenti il codice di stato HTTP che indica che la risorsa richiesta non esiste.